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

时间:2015-06-09 14:58:24

标签: c# linq-to-sql automapper

我有以下两个表:

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 to 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);

这很好,因为:

  • 快速
  • 清洁
  • 最小代码工作量......通过添加或删除列,当子表发生更改时。只要Class Child和Table Child具有相同的属性/列名称,您就可以继续使用。 AutoMapper可以解决问题。

缺点:

  • 我正在为每个新的ChildDTO使用多个“ResolveCore”锤击SQL。

你们怎么想?是否有一种神奇的方法可以仅在一次拍摄中解决Child to ChildDTO,没有手动映射,没有锤击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;

1 个答案:

答案 0 :(得分:0)

我会使用带有修改的automapper来处理你的方法。将父成员添加到您的Child类。然后,您可以直接在查询中加载它(Loading Related Entities),这样您就可以在Child实例中使用它而不使用automapper解析器,并且不会对单个子项进行多次查询。

另外,你可以考虑其他地图制作者。我们从使用automapper切换到emitmapper,因为我们发现它的执行速度提高了约10倍。但这需要进行一些测试,我们将复杂的课程分为几个级别。