2014-01-15 63 views
1

我已將計算字段(ActiveCreditsLeft)直接添加到我的CodeFirst實體類中。在CF Entity類中添加計算字段邏輯是否好主意?EF實體類中的CF代碼首先計算字段

public class User : Entity 
    { 
     public User() 
     { 
      Id = Helper.GetRandomInt(9); 
      DateStamp = DateTime.UtcNow; 
      TimeZone = TimeZoneInfo.Utc.Id; 
     } 

     [DatabaseGenerated(DatabaseGeneratedOption.None)] 
     public int Id { get; set; }    
     [Required] 
     [MaxLength(50)] 
     public string Email { get; set; } 
     [Required] 
     [MaxLength(50)] 
     public string Password { get; set; } 
     [MaxLength(50)] 
     public string FirstName { get; set; } 
     [MaxLength(50)] 
     public string LastName { get; set; } 
     [Required] 
     public DateTime DateStamp { get; set; }   

     public virtual ICollection<Order> Orders { get; set; } 
     public virtual ICollection<Statistic> Statistics { get; set; } 
     public virtual ICollection<Notification> Notifications { get; set; } 


     [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
     public bool Active 
     { 
      get 
      { 
       return Orders.Any(c => c.Active && (c.TransactionType == TransactionType.Order || c.TransactionType == TransactionType.Subscription)); 
      } 
     } 

     [DatabaseGenerated(DatabaseGeneratedOption.Computed)] 
     public int CreditsLeft 
     { 
      get 
      { 
       return Orders.Sum(p => p.Credits != null ? p.Credits.Value : 0); 
      } 
     } 

    } 

回答

1

是好主意,加入CF實體類的內部計算字段的邏輯?

當然,你可以做到這一點,但有幾件事你必須照顧。

首先,由業務邏輯計算的屬性的屬性不是[DatabaseGenerated(DatabaseGeneratedOption.Computed)],因爲這表示該值是在數據庫中計算的(如在計算列中)。您應該通過[NotMapped]屬性標記屬性。這告訴實體框架忽略數據庫映射中的屬性。

其次,由於兩個屬性都使用Orders,因此您必須確保訂單已加載或可以在訪問任一屬性時進行延遲加載。因此,您可能需要使用Include聲明(Include(user => user.Orders))加載User。否則,您必須確保在訪問ActiveCreditsLeft時環境仍然存在。

第三,你不能直接在EF LINQ查詢處理性能,如

db.Users.Select(u => u.Active); 

因爲EF會拋出異常,它不知道Active。您只能在內存中的物化用戶對象上尋址屬性。