将表达式传递给IEnumerable选择

时间:2017-01-10 12:27:36

标签: c# .net entity-framework expression ienumerable

我正在尝试从数据库实体到应用程序读取模型编写自定义映射。

假设我有2个实体

public class A
{
    public string One {get; set;}
    public string Two {get; set;}
    public ICollection<B> Three {get;set;}

}

public class B
{
    public string SomeProp {get; set;}
    public string SomeProp2 {get; set;}
}

我正在尝试将这些实体映射到阅读模型。

public class AReadModel
{
    public string One {get; set;}
    public string Two {get; set;}
    public ICollection<BReadModel> Three {get;set;}
    public bool Deletable {get; set;}

}

public class BReadModel
{
    public string SomeProp {get; set;}
    public string SomeProp2 {get; set;}
}

此关系中的实体B是Collection,但在另一个中它可以是独立的1:1或1:0实现,因此我想定义A和AReadModel之间的映射以及B和BReadModel作为表达式将作为IQueryable Select传递()。关键是我想重用我的映射B - &gt; BReadModel定义为A - &gt; AReadModel并将其定义为IQueryable自定义扩展。

public static class BMapping
{
    public Expression<Func<B,BReadModel>> expression = instance => new BReadModel
    {
        SomeProp = instance.SomeProp,
        SomeProp2 = instance.SomeProp
    };

    public static IQueryable<BReadModel>ToReadModel(this IQueryable<B> source)
    {
        return this.Select(expression);
    }
}

public static class AMapping
{
    public Expression<Func<A,AReadModel>> expression = instance => new AReadModel
    {
        One = instance.One,
        Two = instance.Any,
        Deletable = Three.Any(),
        Three = instance.Three.Select(BMapping.expression) // this will not work cuz Three is collection and it requires Func<B,BReadModel> yet i need an expression here, otherwise EF won't be able to translate it. Of course I could just explicitly define mapping here again and it would work but it will lead to maintenance hell.

    public static IQueryable<AReadModel>ToReadModel(this IQueryable<A> source)
    {
        return this.Select(expression);
    }
}

所以问题是:是否有可能重复使用AMapping中嵌套集合的映射定义中的BMapping中定义的映射?

2 个答案:

答案 0 :(得分:2)

您可以使用Compile()类的Expression方法返回相应的委托(请参阅https://msdn.microsoft.com/en-us/library/bb345362(v=vs.110).aspx)。

答案 1 :(得分:1)

通常需要一些表达式后期处理,例如https://msdn.microsoft.com/en-us/library/jj127316(v=vs.85).aspx multiples = 2 4 6 / AsExpandable / Invoke,但幸运的是,在此特定情况下,您只需使用Expand应用表达式,这是最新的EF6支持。

因此,假设AsQueryableexppression类的静态成员,则以下内容应该有效:

BMapping