使用 Linq-to-SQL 查询和映射复杂对象

Querying and mapping complex objects using Linq-to-SQL

我有以下两个表:

ChildTable
ID  ManyColumns ParentID
1   XXXX        1
2   YYYY        1
3   ZZZZ        4

ParentTable
ID  Name
1   aaaa
2   bbbb
3   cccc
4   dddd

我有以下 类 表示上述表格:

public class Child  
{
    public string ID { get; set; }
    public string ManyColumns { get; set; }
    public string ParentID { get; set; }
}

public class Parent
{
    public string ID { get; set; }
    public string Name { get; set; }
}

但是对于数据传输,我有相应的 类:

public class ChildDTO  
{
    public string ID { get; set; }
    public string ManyColumns { get; set; }
    public ParentDTO Parent { get; set; } //Here is the only IMPORTANT difference
}

public class ParentDTO  
{
    public string ID { get; set; }
    public string Name { get; set; }
}

如何使用 LINQ-to-SQL 将 Child 解析为 ChildDTO:

我知道我可以使用这个选项:

List<ChildDTO> ChildDTOs = (from C in context.Childs
        join P in context.Parents on C.ParentId equals P.Id
        select new ChildDTO(){
            ID = C.ID,
            ManyColumns = C.ManyColumns,
            Parent = P});

但是,我试图避免在 Select 语句中必须执行的多重映射。 此外,Child Class 在当前的 Beta 阶段不断变化。所以,如果我使用上面的选项,我必须不断更新这些映射。

为了编码方便,我是这样使用AutoMapper的

AutoMapper.Mapper.CreateMap<Child, ChildDTO>()
    .ForMember(dst => dst.Parent, opt => opt.ResolveUsing<Resolver_ParentId_to_Parent>().FromMember(src => src.ParentId))

public class Resolver_ParentId_to_Parent : ValueResolver<string, ChildDTO>
{
    protected override ChildDTO ResolveCore(string source)
    {
        return (from P in context.Parents 
                Where P.Id = source.ToString()
                select item).FirstOrDefault();
    }
}

然后,我可以简单地映射它:

List<Child> Childs = (from C in context.Childs select C);
List<ChildDTO> newChildDTOs = AutoMapper.Mapper.Map<List<ChildDTO>>(Childs);

这很好,因为:

缺点:

你们怎么看?有没有一种神奇的方法可以一次性将 Child 解析为 ChildDTO,without 手动映射,without 锤击 SQL? 只是在做梦:

List<ChildDTO> ChildDTOs = (from C in context.Childs
    join P in context.Parents on C.ParentId equals P.Id
    select SuperConversor(new ChildDTO())).ToList;

我会采用你的方法,使用经过修改的自动映射器。将父成员添加到您的子 class。然后您可以直接将其加载到查询中 (Loading Related Entities),这样您就可以在 Child 实例中拥有它,而无需使用自动映射器解析器,也无需对单个子项进行多个查询。

此外,您可以考虑其他映射器。我们从使用 automapper 切换到 emitmapper,因为我们发现它的执行速度快了约 10 倍。但这需要一些测试,我们有复杂的 classes 下降了几个级别。