C#映射两个复杂的对象

时间:2016-05-27 12:52:26

标签: c# .net

我有四个班级:

public class Customer
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public List<Product> Product { get; set; }
}

public class Product
{
    public int ProductNumber { get; set; }

    public string ProductColor { get; set; }
}

///////////////////////////////////////////////

public class Customer_
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public List<Article> Article { get; set; }
}

public class Article
{
    public int ArticleNumber { get; set; }

    public string ArticleColor { get; set; }
}

还有一个例子:

var Cus = new List<Customer>
{
    new Customer()
    {
        FirstName = "FirstName1",
        LastName = "LastName1",
        Product = new List<Product>
        {
            new Product()
            {
                ProductColor = "ProductColor1",
                ProductNumber = 11
            }
        }
    },               
    new Customer()
    {
        FirstName = "FirstName2",
        LastName = "LastName2",
        Product = new List<Product>
        {
            new Product()
            {
                ProductColor = "ProductColor2",
                ProductNumber = 12
            }
        }
    }
};

我想创建一个新对象List<Customer_>,其值为my instance Cus。例如Customer.FirstName = Customer_.FirstName, Customer.Product.ProductColor = Customer_.Article.ArticleColor etc

最简单的方法是使用Dictionary

3 个答案:

答案 0 :(得分:3)

可以通过使用Interface来完成映射。

定义一个接口,该接口提供逻辑命名属性的映射,例如您提到的常见颜色属性:

// Some entities have different named properties but can be joined
// using those properties. This interface shows a common color which 
// when implemented will route the processing to a common shared property
// which reports and sets the associated color.
public interface IDefinedColor
{
    string Color { get; set; }
}

如果您必须为partialProduct创建Article个类,并让它们遵守所述接口。 如果使用像EF这样的实体映射器,这是使用部分进行此类maping的好方法。实现接口和挂钩的通用性:

// Holds the common properties for future processing.
public partial class Product : IDefinedColor
{
    public string Color
    {
        get { return ProductColor; }
        set { ProductColor = value; }
    }
}

然后根据需要处理IDefinedColor 映射的实现。

通过使用接口,可以让所有未来的开发人员知道在属性中指定业务逻辑相等性的合同,并且不会在其他加入类中隐藏。

答案 1 :(得分:1)

这取决于这些组件之间的关系,但我只是将构造函数添加到接受Customer对象的Customer_。然后你调用它来执行转换。 e.g。

public class Article
{
   public Article(Product source)
   {
      this.ArticleNumber = source.ProductNumber;
      this.ArticleColor = source.ProductColor;
   }
}

public class Customer_
{
    public Customer_(Customer source) 
    {
        this.FirstName = source.FirstName;
        this.LastName = source.LastName;
        this.Article = source.Product.Select(o => new Article(o)).ToList()
    }

    ...
}

//and finally to convert the list you can do something like

//initial list
var Cus = new List<Customer>() { ... etc. }

/converted list
var Cus_ = Cus.Select(o => new Cusomter_(o)).ToList();

编辑:我从上面的评论中看到,您实际上有100个要映射的属性。我可以看到这是一种痛苦。但是,如果您有像Product to Article这样的复杂转换,那么我仍然会按照上面的方式进行手动路由,这样您就可以完全清楚发生了什么。或者,您可以使用继承来使用公共基类或接口重新设计对象,这可能会使映射更容易。

答案 2 :(得分:1)

您可以创建映射器扩展类

public static class MapperExtension
{

public Customer_ Convert(this Customer customer)
{
   return new Customer_()
   {
     FirstName = customer.FirstName,
     LastName = customer.LastName,
     Article = customer.Product.Convert()
   };
}

public static List<Article> Convert(this List<Product> products)
{
    return products.Select(x=> new Article(){
    ArticleNumber = x.ProductNumber,
    ArticleColor = x.ProductColor
    };
}
}

确保引用放置扩展类的正确命名空间。

像这样调用代码

客户是从您的代码填写的列表

List<Customer_> convertedCustomers_ = customers.Select(x=> x.Convert()).ToList();