首先在EF代码中使用计算属性

本文关键字:计算 属性 代码 EF | 更新日期: 2023-09-27 18:17:53

我有这个实体:

 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中不支持指定的类型成员'Duration'实体。只有初始化式、实体成员和实体导航

我错在哪里?

首先在EF代码中使用计算属性

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

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

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

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