在同一方法中映射它的类或子类

时间:2013-12-20 07:59:43

标签: c# .net mapping

编辑: 我在输入这个问题时意识到自己,通过使用泛型可以实现一个简单的解决方案。我正在测试它,并将很快发布...

给定两个实体类(例如,从数据库加载数据):

class PersonFromDb
{
    public string NameFromDb { get; }
    // ... other properties follow...
}

class ChildFromDb
{
    public PersonFromDb Person { get; }
    public int AgeFromDb { get; }
}

...以及下面的“目标”类,我想要映射:

class Person
{
    public string Name{ get; set; }
}

class Child : Person
{
    public int Age {get; set; }
}

现在说我已经编写了一种映射方法,用于将PersonFromDb映射到Person

public Person MapPerson(PersonFromDb person){ 
   return new Person { 
       Name = person.NameFromDb, 
       // ...
   }
}

另一种映射Child的方法:

public Child MapChild(ChildFromDb child){ ... }

我想在此处执行的操作是映射到MapPerson()内的MapChild(),以避免重新映射所有常见属性。

我不能将MapPerson()Child一起使用,因为它会返回Person,而不是Child

有没有任何模式可以帮我解决这个问题,所以我不必在这里重复这么多的映射逻辑?

3 个答案:

答案 0 :(得分:1)

正如我的编辑中提到的,我在写这个问题时意识到使用泛型有一个简单的解决方案:

public T MapPerson<T>(PersonFromDb person) where T : Person, new() { 
   return new T { 
       Name = person.NameFromDb, 
       // ...
   }
}

这将允许以下两种情况:

Person mappedPerson = MapPerson<Person>(instanceOfPersonFromDb);

Child mappedChild = MapPerson<Child>(instanceOfChildFromDb.Person);

然后,我可以从MapChild()调用后者,允许我在MapPerson()中映射公共属性,然后在Child中添加MapChild()中定义的额外属性

答案 1 :(得分:1)

您可以创建通用人物映射器,它将创建并映射任何具有无参数构造函数的人员类型:

public <TPerson> MapPerson<TPerson>(PersonFromDb dbPerson){ 
   where TPerson: Person, new()
   return new TPerson { 
       Name = dbPerson.NameFromDb, 
       // ...
   }
}

然后使用此通用人物映射器来映射孩子:

public Child MapChild(ChildFromDb dbChild)
{
    var child = MapPerson<Child>(dbChild.Person);
    child.Age = dbChild.AgeFromDb;
    return child;
}

答案 2 :(得分:0)

您可以依靠像AutoMapper这样的映射框架来完成这项工作。

另一种解决方案可能是使用接口而不是继承。定义一个由Person et Child对象实现的IPerson接口。然后你的MapPerson函数可能像MapPerson(IPerson目标,PersonFromDb源)那样初始化目标对象,因此能够初始化Person或Child对象。

或者您可以使用组合而不是继承,并使Person对象成为子对象的属性。