【问题标题】:Using calculated property in EF Code First在 EF Code First 中使用计算属性
【发布时间】:2015-08-27 12:56:21
【问题描述】:

我有这个实体:

 public class MyDTO
    {
        int id;
        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        DateTime createdOn;
        public DateTime CreatedOn
        {
            get { return createdOn; }
            set { createdOn = value; }
        }

        DateTime modifiedOn;
        public DateTime ModifiedOn
        {
            get { return modifiedOn; }
            set { modifiedOn = value; }
        }

        int duration;
        public int Duration
        {
            get { return ((TimeSpan)(ModifiedOn - CreatedOn)).Days; }
            protected set { }
        }
}

那个Duration是计算属性,也是这个映射文件:

internal partial class MyDTO_Mapping : EntityTypeConfiguration<MyDTO>
{
    public MyDTO_Mapping()
    {
        this.HasKey(t => t.Id);
        this.ToTable("MyDTO");
        this.Property(t => t.Id);
        this.Property(t => t.CreatedOn).HasColumnName("CreatedOn");
        this.Property(t => t.ModifiedOn).HasColumnName("ModifiedOn");
        this.Ignore(t => t.Duration);
    }
}

但是当我想对该实体进行查询时(我在 where 子句中使用了Duration),我得到了这个错误:

LINQ to 不支持指定的类型成员“持续时间” 实体。只有初始化器、实体成员和实体导航 支持属性。

我的错误在哪里?

【问题讨论】:

  • 在按该属性过滤之前尝试实现(例如调用ToList())。
  • @Giedrius 是完全正确的,你应该把这个写成答案

标签: c# entity-framework ef-code-first


【解决方案1】:

您的 LINQ 查询被转换为 SQL 查询并在 SQL 服务器上执行。服务器不知道您的计算属性,它不会将对Duration 的调用转换为((TimeSpan)(ModifiedOn - CreatedOn)).Days。因此,要访问Duration 的值,您需要先将对象从数据库中取出,然后再对其进行查询。

按照建议,调用 ToList()ToArray() 将实现(从数据库中获取)您的结果。

如果您的持续时间过滤器对性能很重要(例如,它过滤掉许多记录),那么编写一个复制持续时间属性计算的 where 子句可能是明智之举,例如(未经测试):

from d in Context.MyDTOs where (d.ModifiedOn - d.CreatedOn).Days > 10 select d

【讨论】:

  • "写一个 where 子句来复制持续时间属性的计算可能很聪明。"你能解释一下吗?
猜你喜欢
  • 1970-01-01
  • 2013-03-13
  • 2013-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
相关资源
最近更新 更多