执行此操作的“首选”方法是使用包含您关心的属性的接口。
interface IMyProp
{
string SomeProp {get;}
}
class T : IMyProp
{
public string SomeProp
{
get
{
//Some complicated logic
}
}
}
class Y : IMyProp
{
public string SomeProp {get; set;}
}
只需将您的表达式编码为Expression<Func<IMyProp, bool>>
但是可以理解的是,您不能总是这样做,对于这种情况,您可以使用像 AutoMapper 这样的库
class T
{
public string SomeProp
{
get
{
//Some complicated logic
}
}
}
class Y
{
public string SomeProp {get; set;}
}
//Some initiation code somewhere else in your project
public static void InitializeMappings()
{
Mapper.CreateMap<T, Y>();
}
public static IQueryable<Y> FilterOnTAndMapToY(IQueryable<T> source, Expression<Func<T,bool>> filter)
{
return source.Where(filter).Project().To<Y>();
}
现在这不会将您的Expression<Func<T, bool>> 完全转换为Expression<Func<Y, bool>>,但它确实允许您使用T 表达式并在应用过滤后使用它来获得Y 结果。
AutoMapper 的 Queryable Extensions 工作方式是在执行 LinqToEntities 时从 T 到 Y 的查询和转换发生在所有服务器端。所以你甚至可以做
public static IQueryable<Y> MultiFilterCast(IQueryable<T> source, Expression<Func<T,bool>> tTypeFilter, Expression<Func<Y,bool>> yTypeFilter)
{
var filteredStage1 = source.Where(tTypeFilter);
var castToY = filteredStage1.Project().To<Y>();
var filteredStage2 = castToY.Where(yTypeFilter);
return filteredStage2;
}
tTypeFilter 和 yTypeFilter 都将在您获得结果集之前应用到服务器端。