[英]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.