我有一个带有包装的项目 EntityFramework 6.1.0
我正在使用DB-First模型
某些模型实体已通过以下方式扩展:
public interface IVersionable{
int VersionId{get;set;}
}
public interface IEditable{
bool IsEditable{get;set;}
}
public interface IFullFeatures:IVersionable,IEditable{}
public partial EntityOne:IFullFeatures{
//This is the extension partial class for the auto-generated model class EntityOne that already has interface properties
}
public partial EntityTwo:IFullFeatures{
//This is the extension partial class for the auto-generated model class EntityTwo that already has interface properties
}
自动生成的类EntityOne和EntityTwo具有IFullFeatures所需的所有属性,对于EntityTwo自动生成的文件,我们具有以下ICollection:
public virtual ICollection<EntityOne> EntityOne {get;set;}
最后我有了扩展方法:
public static class FeaturesExtensionMethod{
public static IQueryable<T> FilterEditable<T>(this IQueryable<T> source) where T:class,IEditable{
return source.Where(s=>s.IsEditable);
}
public static IQueryable<T> FilterVersion<T>(this IQueryable<T> source, int versionId) where T:class,IVersionable{
return source.Where(s=>s.VersionId==versionId);
}
public static IQueryable<T> FullFilter<T>(this IQueryable<T> source, int versionId) where T:class,IVersionable{
return source.FilterEditable().FilterVersion(versionId);
}
}
然后,在运行时我执行以下操作:
var everyEntitiTwo=ctx.EntityTwo.FullFilter(4).ToList();
没问题,它工作正常并且可以过滤...但是在运行时,我改为执行此操作:
var test= ctx.EntityTwo.Include("EntityOne").Select(et=>et.EntityOne.AsQueryAble().FullFilter(4)).ToList()
我收到此错误:
LINQ to Entities无法识别方法'FullFilter',并且该方法无法转换为商店表达式。
所以问题是:我的扩展方法有什么问题?为什么在第二种情况下甚至在第一种情况下都不会出现此错误?
谢谢。
更新
多亏了乔恩·汉纳(Jon Hanna),我才从这种替代方法中获得了灵感,从而获得了相同的结果:
我创建了一个“代理类”来获取过滤器,因为表达式
public static FilterProxies{
public static GetProxiedFilter<T>(int versionId, bool onlyEditable) where T: class, IFullFeatures{
Expression<Func<T,bool>> filteredExp
if(onlyEditable){
filteredExp=(iff=>iff.VersioneId==versionId&&iff.IsEditable);
}
else{
filteredExp=(iff=>iff.VersioneId==versionId);
}
return filteredExp;
}
}
然后,使用情况:
var filter=FilterProxies.GetProxiedFilter<EntityOne>(4,true);
var test= ctx.EntityTwo.Include("EntityOne").Select(et=>et.EntityOne.AsQueryAble().Where(filter)).ToList()
希望能对这篇文章有所帮助,这要感谢乔恩(Jon)启发我应用此解决方案
答案 0 :(得分:1)
ctx.EntityTwo.FullFilter(4).ToList();
这立即变为
ctx.EntityTwo.Where(s => s.IsEditable).Where(s => s.VersionId == 4).ToList();
Entity Framework当然可以处理。
var test= ctx.EntityTwo.Include("EntityOne").Select(et=>et.EntityOne.AsQueryAble().FullFilter(4)).ToList()
由于在查询中使用使用了可查询扩展,并且作用于另一种可查询类型,因此方法调用是传递给实体框架的表达式的一部分,并且它不知道FullFilter()
会这样做,并在这一点上令人窒息。
答案 1 :(得分:0)
EF无法将FullFilter方法转换为SQL,因为您正在使用LINQ to Entities。您可能需要使用Linq to Objects
ctx.EntityTwo.ToList()在您的方法之前,因此它首先获取对象列表,然后使用该列表执行您的方法,即执行LINQ To Objects