【发布时间】:2015-06-19 06:18:01
【问题描述】:
我一直在尝试提出一种干净且可重用的方法来将实体映射到它们的 DTO。这是我想出的一个例子以及我遇到的问题。
实体
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
// Other properties not included in DTO
}
public class Address
{
public int ID { get; set; }
public string City { get; set; }
// Other properties not included in DTO
}
DTO
public class PersonDTO
{
public int ID { get; set; }
public string Name { get; set; }
public AddressDTO Address { get; set; }
}
public class AddressDTO
{
public int ID { get; set; }
public string City { get; set; }
}
表达式
这就是我开始处理映射的方式。我想要一个在映射之前不会执行查询的解决方案。有人告诉我,如果您传递 Func<in, out> 而不是 Expression<Func<in, out>>,它将在映射之前执行查询。
public static Expressions
{
public static Expression<Func<Person, PersonDTO>> = (person) => new PersonDTO()
{
ID = person.ID,
Name = person.Name,
Address = new AddressDTO()
{
ID = person.Address.ID,
City = person.Address.City
}
}
}
其中一个问题是我已经有一个将Address 映射到AddressDTO 的表达式,所以我有重复的代码。如果person.Address 为空,这也会中断。这会很快变得混乱,特别是如果我想在同一个 DTO 中显示与人员相关的其他实体。它变成了嵌套映射的鸟巢。
我尝试了以下方法,但 Linq 不知道如何处理。
public static Expressions
{
public static Expression<Func<Person, PersonDTO>> = (person) => new PersonDTO()
{
ID = person.ID,
Name = person.Name,
Address = Convert(person.Address)
}
public static AddressDTO Convert(Address source)
{
if (source == null) return null;
return new AddressDTO()
{
ID = source.ID,
City = source.City
}
}
}
有没有我遗漏的优雅解决方案?
【问题讨论】:
-
AutoMapper: automapper.org
-
我以前使用过 AutoMapper,但我假设它必须在映射之前执行查询。在进一步查看文档后,它看起来可能与我正在寻找的内容接近 HERE
-
您的查询将在执行映射时执行,但如果实体中有您不感兴趣的字段,请使用 NHibernate 和 EntityFramework 都可用的
Project().To<>。它将有效地对映射配置中指定的字段执行select。 -
是的,
Project().To<>绝对是要走的路。此外,AutoMapper 可以处理嵌套集合,但对展平的支持有限。
标签: c# linq entity-framework linq-to-sql linq-to-entities