psuedocode中的基本思想
Select(a, b) => new Tuple<List<Item1>, List<Item2>>(a, b)
我试图在以下方面实现这一目标:
以下是涉及的两个类
public class Bundle
{
public Guid Id { get; set; }
public string Name { get; set; }
public HashSet<Inventory> Inventories { get; set; }
}
public class Inventory
{
public Guid Id { get; set; }
public string Name { get; set; }
public int Stock { get; set; }
}
现在我能想到的只是
using (var context = new MyEntities())
{
return new Tuple<IEnumerable<Inventory>, IEnumerable<Bundle>>(context.Inventories.OrderBy(a => a.Stock).ToList()
, context.Bundles.Include(b => b.Inventories).OrderBy(c => c.Name).ToList());
}
然而,这会两次击中数据库。
我知道UNION
用于合并来自2个不同查询的结果集,但这两个查询必须具有相同的列数,因此我假设它在选择相同数据时最佳使用。
如何从两个不同的表中选择数据到两个单独的列表中,只有一次点击?
答案 0 :(得分:2)
如果您想要两个结果集,可以通过抛出两个查询来完成。这可以在一个数据库调用中完成,没有问题,但它不会像您感兴趣的那样神奇地划分为两组对象。
事实上,当建立连接(实例化成本或延迟成本等)的成本足以保证它时,询问多个问题并获得多个结果集是非常常见的。我自己在存储过程中完成了它,在一个查询中询问页面所需的所有内容。
但是,如果性能是关键问题,缓存也很常见。并且,如果这些是下拉列表,或者列表请求的其他内容很小,并且列表不会经常更改,您甚至可以在应用程序启动时将其拉入内存并将其设置在Web服务器上,这样您就不会使数据库旅行。
我不喜欢LINQ to SQL,因为它给DBA带来了麻烦,但是你可以这样做(只有一个例子,你可以链接命令的任何方法都可以):
var connString = "{conn string here}";
var commandString = "select * from tableA; select * from tableB";
var conn = new SqlConnection(connString);
var command = new SqlCommand(commandString, conn);
try {
conn.Open();
var result = command.Execute();
// work with results here
}
finally {
conn.Dispose();
}
我没有填写所有细节,但您可以使用任意数量的命令执行此操作。再一次,如果信息没有改变,可以考虑单击并保持在内存中(通过编程缓存)或使用其他类型的缓存机制。
答案 1 :(得分:1)
如果您担心表现,我不认为减少查询量是最佳选择。事实上,如果你想要细粒度优化,LINQ也不是最合适的工具。
话虽这么说,你可以使两个不同的对象匹配相同的接口/列,为其他类型中缺少的那些填充虚拟属性。理论上,这应该转换为包含所有列的SQL union
。
var union = context.Inventories
.Select(i => new { i.Id, i.Name, i.Stock, Inventories=null })
.Concat(context.Bundles.Select(b => new { b.Id, b.Name, Stock=0, b.Inventories));
答案 2 :(得分:0)
你要求的是不可能的。 如果您尝试获得两个不同的结果,则需要按两次DB,每个结果集一次。你可以做一个外连接,但是这会使你的结果集大于它应该的,并且从你想要一次击中DB的事实来看,你关心性能。 此外,如果性能是一个问题,我不会首先使用Linq。
答案 3 :(得分:0)
我认为你可以通过询问多个结果集来做到这一点(正如格雷戈里已经指出的那样),我不确定这将是什么“最佳”方式。你为什么不看看这篇msdn文章呢? How to: Use Stored Procedures Mapped for Multiple Result Shape
或者,对于linq-to-sql方法: LINQ to SQL: returning multiple result sets