我正在尝试执行正确映射以下内容的查询:
public class A
{
public int Id { get; set; }
public string Name { get; set; }
public int BId {get; set; }
public List<B> { get; set; }
}
public class B
{
public int Id { get; set; }
public string Name { get; set; }
public int CId { get; set; }
public int DId { get; set; }
public C C { get; set; }
public D D { get; set; }
}
public class C
{
public int Id { get; set; }
public string Name { get; set; }
}
public class D
{
public int Id { get; set; }
public string Name { get; set; }
}
如何编写一个正确映射实体A的查询,其中包含填充了C和D的实体B列表?
答案 0 :(得分:1)
您想在此处执行两个查询,以捕获A上B的一对多性质。此外,您的B可能需要在查询中返回A的引用。
var query1 = conn.Query<A>(select * from dbo.A)
var query2 = conn.Query<B,C,D,B>("select * from dbo.B...join C...join
D",(b,c,d)=>{
b.C = c;
b.D = d;
return b;
}
现在你必须将它们连接在一起。我使用linq连接和扩展来自动化它的一堆,但要点是,循环遍历每个'A'并从查询2中找到匹配的'B'。字典和列表也可能比'Where'子句更快,所以你可以写一个优化下面循环的扩展。
foreach(var a in query1){
a.Bs = query2.Where(w=>w.AId.Equals(a.Id));
}
请注意,您可以通过使用QueryMultiple返回多个记录集来减少数据库的访问(如果您的数据库支持该数据集)。
答案 1 :(得分:0)
您可以使用Drapper(建立在Dapper之上)完成对数据库的一次往返。
假设您有一组返回多个结果的SQL查询:
select * from [TableA];
select * from [TableB];
select * from [TableC];
select * from [TableD]
...每个结果都有某种形式的标识符/外键给其他人,你可能会建立一个如下所示的存储库:
public class Repository : IRepository
{
// IDbCommander is a Drapper construct.
private readonly IDbCommander _commander;
public Repository(IDbCommander commander)
{
_commander = commander;
}
public IEnumerable<A> RetrieveAll()
{
// execute the multiple queries and
// pass control to a mapping function.
return _commander.Query(Map.Results);
}
private static class Map
{
internal static Func<IEnumerable<A>,
IEnumerable<B>,
IEnumerable<C>,
IEnumerable<C>,
IEnumerable<A>> Results = (collectionA, collectionB, collectionC, collectionD) =>
{
// map C and D to B based on their Id's
collectionB.C = collectionC.SingleOrDefault(c => c.Id == b.Id);
collectionB.D = collectionD.SingleOrDefault(d => d.Id == b.Id);
// now map B to A.
collectionA.B = collectionB.Where(b => b.Id == a.Id).ToList();
return collectionA;
}
}
}
从内存中键入的示例因此语法可能稍微偏离但你得到了要点。
我同意BlackjacetMack你应该在结果中加入某种形式的分页(在Drapper中也支持)。