LinqToSql和抽象基类

Nic*_*ong 6 c# linq-to-sql

我有一些linq实体继承了这样的东西:

public abstract class EntityBase { public int Identifier { get; } }

public interface IDeviceEntity { int DeviceId { get; set; } }

public abstract class DeviceEntityBase : EntityBase, IDeviceEntity
{
  public abstract int DeviceId { get; set; }
}

public partial class ActualLinqGeneratedEntity : DeviceEntityBase
{
}
Run Code Online (Sandbox Code Playgroud)

在通用方法中,我使用以下命令查询DeviceEnityBase派生实体:

return unitOfWork.GetRepository<TEntity>().FindOne(x => x.DeviceId == evt.DeviceId);
Run Code Online (Sandbox Code Playgroud)

其中TEntity有一个绑定,它是一个DeviceEntityBase.此查询始终失败,并出现InvalidOperationException,并显示消息"类成员DeviceEntityBase.DeviceId未映射".即使我在抽象基类中添加了一些映射信息

[Column(Storage = "_DeviceId", DbType = "Int", Name = "DeviceId", IsDbGenerated = false, UpdateCheck = UpdateCheck.Never)]
Run Code Online (Sandbox Code Playgroud)

Sha*_*ica 5

哇,看起来像我曾经可以单挑@MarcGravell!

我有同样的问题,然后我发现了这个答案,它解决了我的问题!

在你的情况下,你会说:

return unitOfWork.GetRepository<TEntity>().Select(x => x).FindOne(x => x.DeviceId == evt.DeviceId);
Run Code Online (Sandbox Code Playgroud)

而鲍勃是你的叔叔!


Mar*_*ell 4

LINQ-to-SQL通过鉴别器对继承提供一些支持(此处此处),但您只能查询 LINQ 模型中定义的类 - 即数据类本身,以及(对于本例来说更重要)查询其本身必须用数据类来表述:虽然 TEntity 是一个数据类,但它知道这里的属性是在实体基础上声明的。

一种选择可能是动态表达式;它是类本身声明的属性(即丢失基类,但保留接口) - 但这并不是微不足道的。

表达式工作如下所示,请注意您可能希望将字符串作为参数传递,或者通过反射获取主键(如果有属性):

static Expression<Func<T, bool>> BuildWhere<T>(int deviceId) {
    var id = Expression.Constant(deviceId, typeof(int));
    var arg = Expression.Parameter(typeof(T), "x");
    var prop = Expression.Property(arg, "DeviceId");
    return Expression.Lambda<Func<T, bool>>(
        Expression.Equal(prop, id), arg);
}
Run Code Online (Sandbox Code Playgroud)