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

Possible to wrap Expression<> and Func<> after Func defined?

我在我的视图模型中创建了两种几乎相同的映射函数以从 POCO 进行映射,一种用于可查询对象,一种用于 Collections。是否可以创建一种同时执行这两种操作的方法,以便我可以删除重复的代码?我只想保留 Expression<Func<>> 然后在本地 Collections 和 Entity Framework.

上使用它
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 在本地 Collections.

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

在本地 collections 上使用 AsMap 失败并出现 Non-invocable member 错误。还有一些失败的:

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

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

怎么样

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();

这并没有什么坏处,因为你只做一次,但你会立即摆脱重复的代码。

您需要直接传递委托:

Select( ImportPattern.ToMap.Compile() )

注意Compile()是慢调用;你应该缓存它的结果。