2012-01-09 51 views
2

我想简单地加载一个实体,修改一个属性,然后将其保存回数据库。修改实体框架中的实体属性导致验证错误

var db = new NewsletterContext(); 
var newsletter = db.Newsletters.Find(x => x.ID==newsletterID); 
newsletter.SomeProperty = 5; 
db.SaveChanges(); 

这导致验证错误,因为有这是必需的,当我做了Find()显然没有装载通讯对象的某些特性。

我可以使用Include()每个需要的属性跟一个Where()解决这个问题:

var db = new NewsletterContext(); 
var newsletter = db.Newsletters.Include(x => x.RequiredProp1) 
        .Include(x => x.RequiredProp2).Include(x => x.RequiredProp3) 
        .Where(x => x.ID==newsletterID) 
        .FirstOrDefault(); 
db.SaveChanges(); 

这是不是一个非常优雅的解决方案,如果我增加更多的所需性能的Newsletter对象将打破。

有没有更好的解决方案?

+0

是的,对不起,只是术语。 RequiredProp1等实际上是相关的实体。通讯实体本身加载正常,我可以阅读所有的属性,但回退导致错误。 – Judo 2012-01-09 06:11:53

+0

EF 4.1在MVC 3应用程序中首先使用.NET 4.0进行编码。 – Judo 2012-01-09 06:31:04

回答

6

实体框架将在执行验证时禁用延迟加载。因此,如果您对导航属性进行必要的验证,验证将失败。您可以修饰与导航属性相关的标量属性。

public class Foo 
{ 

    [Required] 
    public int? RequiredScalarId { get; set; } 

    public virtual Bar RequiredNavigationalProp { get; set; } 
} 
+0

这不只是添加另一个(可能不必要的)字段到数据库?有没有一种方法来编程启用lazyloading验证? – Judo 2012-01-09 06:38:04

+0

@Judo由于确切原因,延迟加载验证被禁用。避免不必要的延迟加载。具有标量属性就像在这种情况下一样方便。它不会将字段添加到数据库。 – Eranga 2012-01-09 06:45:59

1

不想用foriegn键污染你的模型?好!请继续阅读。 相反,您可以覆盖NewsletterContext中的SaveChanges方法。 获取所有修改过的实体和使用反射,使用下面的示例语法加载所有的延迟加载的属性和集合:

db.Entry(newsletter).Reference(n => n.RequiredProp1).Load(); 
db.Entry(newsletter).Collection(n => n.RequiredCollec1).Load(); 

,因为它听起来这不会是容易的,但一旦你写它,它会感觉很好,看到它无缝工作:)