EF代码首先在CF实体类中计算字段

时间:2014-01-15 09:48:11

标签: linq entity-framework ef-code-first

我已将计算字段(ActiveCreditsLeft)直接添加到我的CodeFirst实体类中。在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 个答案:

答案 0 :(得分:1)

  

在CF实体类中添加计算字段逻辑是否是个好主意?

当然,你可以做到这一点,但有一些事情你必须要照顾。

首先,由业务逻辑计算的属性的属性不是[DatabaseGenerated(DatabaseGeneratedOption.Computed)],因为这表示该值是在数据库中计算的(如在计算列中)。您应该使用[NotMapped]属性标记该属性。这告诉实体框架忽略数据库映射中的属性。

其次,由于两个属性都使用Orders,因此必须确保在访问任一属性时加载订单或者可以延迟加载。因此,您可能希望使用User语句(Include)加载Include(user => user.Orders)。否则,在访问ActiveCreditsLeft时,您必须确保上下文仍然有效。

第三,您无法直接在EF LINQ查询中处理属性,如

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

因为EF会抛出一个不知道Active的异常。您只能在内存中的物化用户对象上处理属性。