我有一个继承了这样的一些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
{
}
在一个通用的方法,我查询DeviceEnityBase派生实体:
return unitOfWork.GetRepository<TEntity>().FindOne(x => x.DeviceId == evt.DeviceId);
其中TEntity有contraint是它DeviceEntityBase。 此查询总是与消息“类构件DeviceEntityBase.DeviceId是未映射的”一个InvalidOperationException失败。 即使我在抽象基类添加一些映射信息
[Column(Storage = "_DeviceId", DbType = "Int", Name = "DeviceId", IsDbGenerated = false, UpdateCheck = UpdateCheck.Never)]
LINQ到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);
}
哇,看起来像有一次我或许可以一起来@MarcGravell!
我有同样的问题,后来我发现这个答案 ,它解决了这个问题对我来说!
在你的情况,你会说:
return unitOfWork.GetRepository<TEntity>().Select(x => x).FindOne(x => x.DeviceId == evt.DeviceId);
和鲍勃是你的叔叔!
这种heirarchial映射的状态并没有可能的LinqToSql。 该映射是设置它不能映射到在基类的属性。 我绕到这个好几个月,当它第一次出来。 最好的解决办法是使用实体框架。 它为您提供了创建对象模型更多的灵活性。 它可以让你做什么你想在这里做。
这里是关于实体框架的一些信息: MSDN文章
尝试.OfType<>()
作为贴在这里https://stackoverflow.com/a/17734469/3936440 ,工作对我来说具有完全相同的问题。