可以包装Expression<>和Func<>在Func定义之后?

时间:2015-06-02 21:22:16

标签: c# expression-trees

我在View Models中创建了两种几乎相同的映射函数,用于从POCO映射,一个用于Queryable,另一个用于Collections。是否可以创建一个同时执行这两个操作的方法,以便删除重复的代码?我只想保留Expression<Func<>>,然后在本地馆藏和实体框架上使用它。

public class MyViewModel
{   
    public static readonly Expression<Func<MyPOCO, MyViewModel>> AsMap =
        (e) => new ImportPattern
        {    id = e.id,
             name = e.name
        }

    public static readonly Func<MyPOCO, MyViewModel>> ToMap =
        (e) => new ImportPattern
        {    id = e.id,
             name = e.name
        }

    public int id { get; set; }
    public string name { get; set; }
}

示例:AsMap成功使用Entity Framework仅投影映射函数中列出的字段。

var a = Product
        .Where(p => p.id > 0 && p.id < 10)
        .OrderBy(q => q.id)
        .Select( ImportPattern.AsMap );

ToMap成功处理本地集合。

var products = Products.Where( p => p.id > 0 && p.id < 10).ToList();
var a = products
      .OrderBy(q => q.id)
      .Select( ImportPattern.ToMap );

在本地集合上使用AsMap失败,出现Non-invocable member错误。这还有一些失败:

.Select( ImportPattern.ToMap.Compile().Invoke() )
.Select( o => ImportPattern.ToMap.Compile().Invoke(o) )

仅供参考,请不要寻找AutoMapper()答案。

2 个答案:

答案 0 :(得分:3)

怎么样?
public static readonly Expression<Func<MyPOCO, MyViewModel>> AsMap =
    (e) => new ImportPattern
    {    id = e.id,
         name = e.name
    }

public static readonly Func<MyPOCO, MyViewModel>> ToMap = AsMap.Compile();

因为你只做了一次,所以并没有真正受到伤害,但你立即摆脱了重复的代码。

答案 1 :(得分:2)

您需要直接传递委托:

Select( ImportPattern.ToMap.Compile() )

请注意Compile()是一个慢速通话;你应该缓存它的结果。