使用 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 Table 通过添加或删除列进行了更改。只要 Class Child 和 Table Child 使用相同的 properties/column 名称是最新的,你就可以继续使用。 AutoMapper 可以解决问题。
缺点:
- 我正在为每个新的 ChildDTO 设置 SQL 倍数 "ResolveCore"。
你们怎么看?有没有一种神奇的方法可以一次性将 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 下降了几个级别。
我有以下两个表:
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 Table 通过添加或删除列进行了更改。只要 Class Child 和 Table Child 使用相同的 properties/column 名称是最新的,你就可以继续使用。 AutoMapper 可以解决问题。
缺点:
- 我正在为每个新的 ChildDTO 设置 SQL 倍数 "ResolveCore"。
你们怎么看?有没有一种神奇的方法可以一次性将 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 下降了几个级别。