创建通用表达式

时间:2013-09-20 18:28:05

标签: c# generics lambda expression

我遇到有关通用表达式的问题。

我有Expression<Func<T, bool>>,我想将Expression<Func<T, bool>>转换为Expression<Func<Y, bool>>。类T的对象具有与类Y相同的属性。

有人知道如何解决这个问题吗?

1 个答案:

答案 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工作方式是从TY的查询和强制转换发生在所有服务器端。所以你甚至可以做到

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;
}
在获得结果集之前,

tTypeFilteryTypeFilter应用于服务器端。