3

我有如下模型:如何處理實體框架4.1中的「計算」屬性?

public class Post 
{ 
    public int Id {get;set;} 
    public virtual ICollection<Comment> Comments {get;set;} 
    public virtual ICollection<Reader> Readers {get;set;} 
    public int Value {get;set;} 
} 

規則是值= Comments.Count * 2 + Readers.Count。

什麼是正確和方便的方式來處理「計算」屬性的「價值」?

我認爲當評論或讀者添加/刪除元素時,「價值」可以被自動計算和保存,這是最好的。

但「DatabaseGeneratedAttribute」在這裏似乎沒有用。

謝謝!

回答

3

這不支持。如果linq-to-entities查詢未映射到數據庫列,則無法使Value可用。如果EF使用EDMX進行映射,有時候可以通過使用自定義映射SQL函數或model defined function來解決,但代碼優先映射不支持任何該功能。其他方法是創建數據庫視圖並映射您的實體以查看,但在這種情況下,實體將是隻讀的。

一旦使用.NET代碼來定義值,它始終只有從數據庫加載的數據計算出的客戶端屬性。如果每次需要可觀察的集合時都不想重新計算屬性,並且每次集合更改時事件處理程序都會更改預先計算的值。

DatabaseGenerated屬性只是將您的屬性標記爲由數據庫生成 - 在這種情況下,您無法更改其值,數據庫必須確保將正確的值存儲在您的表中。

3

我認爲你的列值是基於兩個映射的屬性。使用NotMappedAttribute從數據庫架構排除屬性並在運行時加載值。

public class Post 
{ 
    public int Id {get;set;} 
    public virtual ICollection<Comment> Comments {get;set;} 
    public virtual ICollection<Reader> Readers {get;set;} 

    [NotMapped] 
    public int Value 
    { 
     get return Comments.Count * 2 + Readers.Count; 
    } 
} 
+1

Value不能在Linq to Entity中使用:例如var q = db.Posts.Where(p => p.Value> 100)。而且,表現並不好。該值將在每次計算。 – Chance

0

您可以使用DatabaseGenerated屬性,然後在db中創建觸發器來計算Value。您可以在遷移或db種子方法中創建觸發器。