[英]Cast Entity to Implemented Interface in a Generic Method Using LINQ for Entity Framework
我有一个通用的方法来查询EF中TEntity类型的对象。 如果TEntity实现特定接口,我想将条件添加为where子句。 我的方法是:
public TEntity GetByUserID(Guid userID)
{
var query = this.DbSet;
if (typeof (TEntity).IsImplementationOf<IDeletableEntity>())
{
query = query
.Where((x => !((IDeletableEntity)x).IsDeleted);
}
return query
.FirstOrDefault(x => x.UserID == userID);
}
IsImplementationOf <>()是一个方法,它只是返回true / false,顾名思义。
当我为实现IDeletableEntity的实体地址运行它时,我收到一个错误:
无法将类型“地址”强制转换为“IDeletableEntity”。 LINQ to Entities仅支持转换EDM原语或枚举类型。
我有什么想法可以解决这个LINQ限制?
这是一个有效的解决方案:
public TEntity GetByUserID(Guid userID, params Include<TEntity>[] includes)
{
var query = this.DbSet;
query = Where<IDeletableEntity>(query, x => !x.IsDeleted);
return query
.FirstOrDefault(x => x.UserID == userID);
}
public static IQueryable<TEntity> Where<TPredicateWellKnownType>(IQueryable<TEntity> query, Expression<Func<TPredicateWellKnownType, bool>> predicate)
{
if (typeof(TEntity).IsImplementationOf<TPredicateWellKnownType>())
{
query = ((IQueryable<TPredicateWellKnownType>)query)
.Where(predicate)
.Cast<TEntity>();
}
return query;
}
如果所有DbSets都具有'UserID'属性,则创建另一个名为'IUserID'的接口,然后尝试以下代码:
protected TEntity GetByUserID<TEntity>(Guid userID) where TEntity : class
{
var user = this.Set<TEntity>()
.ToList()
.Cast<IDeletableEntity>()
.Where(u => (!u.IsDeleted))
.Cast<IUserID>()
.Where(u => (u.UserID == userID))
.FirstOrDefault();
return user;
}
我认为问题可能是您在语句中执行的直接转换以及查询可能正在实现枚举类型,因此IDeletable不会在一个实体上实现。
提出这个解决方案
return query.ToList()
.Cast<IDeletable>()
.Where( e => e.Deleted )
.Cast<T>();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.