LinqToSql和抽象基类

时间:2008-10-01 03:23:08

标签: 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
{
}

在通用方法中,我使用:

查询DeviceEnityBase派生实体
return unitOfWork.GetRepository<TEntity>().FindOne(x => x.DeviceId == evt.DeviceId);

其中TEntity有一个禁令,即DeviceEntityBase。此查询始终失败,并出现InvalidOperationException,并显示消息“类成员DeviceEntityBase.DeviceId未映射”。即使我使用

在抽象基类中添加一些映射信息
[Column(Storage = "_DeviceId", DbType = "Int", Name = "DeviceId", IsDbGenerated = false, UpdateCheck = UpdateCheck.Never)]

4 个答案:

答案 0 :(得分:5)

哇,好像曾经有一次我可以单挑@MarcGravell!

我遇到了同样的问题,然后我发现了this answer,它解决了我的问题!

在你的情况下,你会说:

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

鲍勃是你的叔叔!

答案 1 :(得分:4)

LINQ-to-SQL通过鉴别器(herehere)具有某些对继承的支持,但您只能查询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);
}

答案 2 :(得分:1)

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

以下是有关实体框架的一些信息:MSDN Article

答案 3 :(得分:0)

尝试.OfType<>()发布在https://stackoverflow.com/a/17734469/3936440,这对我来说有同样的问题。