2012-01-09 48 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(); 

,因爲它聽起來這不會是容易的,但一旦你寫它,它會感覺很好,看到它無縫工作:)