我遇到有关通用表达式的问题。
我有Expression<Func<T, bool>>
,我想将Expression<Func<T, bool>>
转换为Expression<Func<Y, bool>>
。类T
的对象具有与类Y相同的属性。
有人知道如何解决这个问题吗?
答案 0 :(得分:1)
“首选”方法是使用包含您关注的属性的接口。
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
结果已应用过滤。
当您执行LinqToEntities时,AutoMapper的Queryable Extensions工作方式是从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
应用于服务器端。