У меня есть проект с пакетом 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, и этот метод нельзя преобразовать в выражение хранилища.
Итаквопрос в том, что не так в моих методах расширения?Почему я получаю эту ошибку во втором случае, а не даже в первом?
Спасибо.
ОБНОВЛЕНИЕ
Благодаря Джону Ханне я вдохновилсяк этому альтернативному способу достижения того же результата:
Я создал «прокси-класс» для получения фильтра, потому что Expression > строго типизирован, и мне нужно что-то более общее:
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()
Надеюсь, что буду полезен при обновлении этого поста, спасибо Джону за то, что он вдохновил меня применить это решение