LinqToSql和抽象基类

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

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 { } 

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

 return unitOfWork.GetRepository().FindOne(x => x.DeviceId == evt.DeviceId); 

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

 [Column(Storage = "_DeviceId", DbType = "Int", Name = "DeviceId", IsDbGenerated = false, UpdateCheck = UpdateCheck.Never)] 

LINQ-to-SQL通过鉴别器( 这里 , 这里 )支持inheritance,但是你只能查询LINQ模型中定义的类 – 即数据类本身,以及(更重要的是这个例子)查询本身必须用数据类来表达:虽然TEntity是一个数据类,但它知道这里的属性是在实体基础上声明的。

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

表达式工作如下所示,注意您可能希望将字符串作为参数传入,或者通过reflection获取主键(如果它被归因):

 static Expression> BuildWhere(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>( Expression.Equal(prop, id), arg); } 

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

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

在你的情况下,你会说:

 return unitOfWork.GetRepository().Select(x => x).FindOne(x => x.DeviceId == evt.DeviceId); 

而鲍勃是你的叔叔!

LinqToSql无法实现这种层次映射。 映射已设置,无法映射到基类中的属性。 第一次出现时,我在这里花了几个月的时间。 最好的解决方案是使用entity framework。 它为您创建对象模型提供了更大的灵活性。 它将允许您完成您在此尝试做的事情。

以下是有关entity framework的一些信息: MSDN文章

尝试.OfType<>()发布在这里https://stackoverflow.com/a/17734469/3936440 ,它适用于我有完全相同的问题。