组成复合DTO的表达式树 [英] Composing expression trees for composite DTO

查看:83
本文介绍了组成复合DTO的表达式树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有以下3个DTO

Let's say I have the 3 followings DTOs

public class Mailing
{
    public long Id { get; set; }
    //...

    public long IdSender  { get; set; }
    public Sender Sender { get; set; }

    public long IdTemplate { get; set; }
    public Template Template { get; set; }
}
public class Sender
{
    public long Id { get; set; }
    public string Email { get; set; }
    //...
}
public class Template
{
    public long Id { get; set; }
    public string Name { get; set; }
    //...
}

我有3个表达式树来管理DAO到DTO的转换:

And I have 3 expression trees to manage DAO-to-DTO conversion :

private static readonly Expression<Func<DaoMailing, Mailing>> ToMailingShort =
        input => new Mailing
                        {
                            Id = input.Id,
                            IdSender = input.IdSender,
                            IdTemplate = input.IdTemplate,
                            // ...
                        };

private static readonly Expression<Func<DaoTemplate, Template>> ToTemplate =
        input => new Template
                        {
                            Id = input.Id,
                            Name = input.Name,
                            // ...
                        };


private static readonly Expression<Func<DaoSender, Sender>> ToSender =
        input => new Sender
                        {
                            Id = input.Id,
                            Email = input.Email,
                            // ...
                        };

如何从上面的3中构建给定表达式?

How can I build the given expression from the 3 above ?

private static readonly Expression<Func<DaoMailing, DaoTemplate, DaoSender, MailingFull>> ToMailingFull =
        (input, template, sender) => new Mailing
                        {
                            Id = input.Id,
                            IdSender = input.IdSender,
                            IdTemplate = input.IdTemplate,
                            // ...
                            Template = new Template
                            {
                                Id = template.Id,
                                Name = template.Name,
                                // ...
                            },
                            new Sender
                            {
                                Id = sender.Id,
                                Email = sender.Emai;,
                                // ...
                            }
                        };

很明显,目标是避免重写复合转换中的每个转换

The goal being, obviousely, to avoid rewriting each individual conversion in the composite one

推荐答案

简短的答案是使用 AutoMapper ,或将编译后的表达式转换为函数。在C#中,函数的编写很容易,而表达式的编写则更加困难。

The short answer is use AutoMapper, or the compiled expressions into functions. It is easy in C# to compose functions, much harder to compose expressions.

更长的答案是可能的,但这并不容易。您的代码使用友好的 Expression语法,但实际上要混合使用&匹配表达式,您将需要使用不友好的版本,该版本更难看且更难维护:

The longer answer is that this is possible, but not easy. Your code uses the 'friendly' Expression syntax, but to really mix & match the expressions, you would need to use the unfriendly version, which is much uglier and harder to maintain:

    private static readonly Expression<Func<DaoMailing, DaoTemplate, DaoSender, Mailing>> ToMailingFull =
        (Expression<Func<DaoMailing, DaoTemplate, DaoSender, Mailing>>)Expression.Lambda(
            Expression.MemberInit(
                Expression.New(typeof(Mailing).GetConstructor(Type.EmptyTypes)),
                (ToMailingShort.Body as MemberInitExpression).Bindings
                    .Concat(new List<MemberBinding>{
                        Expression.MemberBind(typeof(Mailing).GetProperty("Sender"), (ToSender.Body as MemberInitExpression).Bindings),
                        Expression.MemberBind(typeof(Mailing).GetProperty("Template"), (ToTemplate.Body as MemberInitExpression).Bindings)
                    })
            ),
            ToMailingShort.Parameters[0],
            ToTemplate.Parameters[0],
            ToSender.Parameters[0]
        );

这篇关于组成复合DTO的表达式树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆