LinqToSql和抽象基类(LinqToSql and abstract base classes

2019-07-23 04:45发布

我有一个继承了这样的一些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)]

Answer 1:

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);
}


Answer 2:

哇,看起来像有一次我或许可以一起来@MarcGravell!

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

在你的情况,你会说:

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

和鲍勃是你的叔叔!



Answer 3:

这种heirarchial映射的状态并没有可能的LinqToSql。 该映射是设置它不能映射到在基类的属性。 我绕到这个好几个月,当它第一次出来。 最好的解决办法是使用实​​体框架。 它为您提供了创建对象模型更多的灵活性。 它可以让你做什么你想在这里做。

这里是关于实体框架的一些信息: MSDN文章



Answer 4:

尝试.OfType<>()作为贴在这里https://stackoverflow.com/a/17734469/3936440 ,工作对我来说具有完全相同的问题。



文章来源: LinqToSql and abstract base classes