我遇到了问题而且不知道如何解决它。想象一下,你有一个List<int>
,其中有大约6000个唯一ID,它与一个表的id匹配,在sql数据表中有大约一百万条记录。我想从我的c#程序中选择那些通过LINQ匹配那些id的记录。我不想使用Contains()
,因为它的翻译速度很慢而且参数列表变得很大。
任何其他想法如何解决这个问题?
关于我的场景(这不是真实的,但类似的场景):
我有一个连接到数据库的服务。例如,客户端请求一批项目,例如Person。服务接受请求,查询数据库并将数据发送回客户端。
Person =(PersonID,Prename,Lastname)
现在客户持有临时人员名单。使用其他方法,我想从服务中检索这些人的地址。所以我将一个PersonID列表添加到服务中,该列表应该返回一个引用这些人的地址列表。
答案 0 :(得分:5)
我不推荐这个。作为LINQ的绝佳工具,在某些情况下,通过处理代码端来尝试智能处理数据可能对应用程序性能非常不利。
你有一个这些Id的列表,如果它们在数据库中,为什么不将整个操作作为存储过程而只返回结果,这样你就不必将昂贵的查询推送到电线,它都在您的数据库中,因此您可以最大限度地减少流量,并可能提高响应速度。
6000项可能看起来不是很麻烦,但实际上如你所说,当尝试使用大小的数据集进行选择时,这可能是一个噩梦。
答案 1 :(得分:3)
一些想法:
将6000个ID插入临时表,并将该临时表连接到您的百万记录表。
使用Contains()并分批选择n,其中N = 500,1000等,而不是一次全部6000。
使用Contains()将使linq创建一个非常大的SQL语句。
答案 2 :(得分:3)
如果您使用的是Entity Framework(EF),则可以在数据(数据)和表格(客户)之间使用内部联接
void Main()
{
var data = Enumerable.Range(1, 6000);
var result = from x in data
join y in Customers
on x equals y.CustomerID
select x;
result.Dump();
}
答案 3 :(得分:1)
通常,我发现xml对于ID的大IN条件表现最佳。它还可以在SQL Server中获取2100个最大参数,如果在LINQ中执行包含,则会遇到这些参数。
我建议:
答案 4 :(得分:0)
只是为了解决这个问题......
var joinTry = from company in dc.Companies
join id in list on company.CompanyID equals id
select company;
不起作用。 LinqToSql不会让你加入。 “除了Contains运算符之外,本地序列不能用于查询运算符的LINQ to SQL实现。”
var containsTry = from company in dc.Companies
where list.Contains(company.CompanyID)
select company;
有效吗?在可预测的
SELECT [t0].[CompanyID], [t0].[CompanyName]
FROM [Company] AS [t0]
WHERE [t0].[CompanyID] IN (@p0, @p1, @p2, @p3, @p4, @p5, ...
方式......就像这样脏,没有更快的方法来获取SQL服务器的int列表。任何调用的开销时间都比任何解析都要大得多。
SELECT
c.CompanyId,
c.CompanyName
FROM Company c
WHERE CompanyID IN (1,2,3,4,5,6,7,8,9,10)
...与...的执行速度相同(由LINQ生成)
exec sp_executesql N'SELECT [t0].[CompanyID], [t0].[CompanyName]
FROM [Company] AS [t0]
WHERE [t0].[CompanyID] IN (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9)',N'@p0 int,@p1 int,@p2 int,@p3 int,@p4 int,@p5 int,@p6 int,@p7 int,@p8 int,@p9 int',@p0=1,@p1=2,@p2=3,@p3=4,@p4=5,@p5=6,@p6=7,@p7=8,@p8=9,@p9=10
......和两倍一样快......
SELECT
c.CompanyId,
c.CompanyName
FROM Company c
/* @Test is a table variable with 1-10 in it */
INNER JOIN @Test t ON t.ID = c.CompanyID
您实际上不需要优化SQL Server对整数列表的处理。在IN()解决方案中,SQL将整数放在它随时生成的索引中。
真正的问题应该是......“我用6000个整数列表代表什么?”并且“我应该把这个清单放在桌子上吗?”。获取6000个整数的客户端列表并将其发送到服务器的任何解决方案都将比使用Contains()的解决方案更加开销。如果你使用LinqToSQL,你必须在某种程度上卖掉范式。
如果这仍然让你感觉很脏,你可以尝试为任意限制列表创建一个表。两列,都是整数。然后,您可以将ID插入该表,然后只使用...
var searchTry = from company in dc.Companies
join search in dc.SearchLists on company.CompanyID equals search.ValueID
where search.SearchID == savedSearchID
select company;