LinqToSql和抽象基类
时间:2020-03-06 14:57:35 来源:igfitidea点击:
我有一些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)]
解决方案
LinqToSql无法实现这种分层映射。映射已设置,它无法映射到基类中的属性。当它第一次问世时,我花了几个月的时间。最好的解决方案是使用实体框架。它为我们创建对象模型提供了更大的灵活性。这将使我们能够完全按照自己的意愿去做。
以下是有关实体框架的一些信息:MSDN文章
LINQ-to-SQL对通过区分符(此处为此处)的继承提供了一些支持,但我们只能查询LINQ模型中定义的类,即数据类本身,以及查询本身(对于此示例可能更重要)必须用数据类来表达:尽管TEntity是数据类,但它知道此处的属性是在实体基础上声明的。
一种选择可能是动态表达式;另一种可能是动态表达式。如果类本身声明了属性(即丢失了基类,但保留了接口),但这并不是一件容易的事。
Expression工作类似于以下内容,请注意,我们可能希望将字符串作为参数传递,或者通过反射(如果有属性)获取主键:
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); }