我有一个简单的表,基本上有一个NVARCHAR Name列和一个DateTime Timestamp列。我想编写一个C#函数,它接受Names和DateTimes的集合,并从我的表中返回名称匹配的所有内容,并且集合中的DateTimes早于表中的DateTimes。
我的非SQL大脑提出的简单方法是创建一个SELECT语句来获取所有匹配的名称(“SELECT Name,Timestamp from MyTable WHERE Name IN(...)”)然后遍历返回的集合比较DateTimes。
使用SQL或Linq必须有更好的方法。我怎样才能更有效地做到这一点?
更新: 感谢您提供的有用反馈!听起来像在这里列出的各种方法运行查询分析器将是要走的路。如果有任何好奇的话,这是另一个扔掉的人:
List<Item> items = ... // this the collection
var db = new ItemDataContext(); // From .Net EF
string[] results = (from item in items
from dbItem in db.Items
where item.Name.Equals(dbItem.Name,StringComparison.InvariantCultureIgnoreCase)
&& item.Timestamp < dbItem.Timestamp
select dbItem.Token).ToArray();
答案 0 :(得分:2)
我有一篇关于传递ID列表的博文: Passing IDs to Stored Procs Using XML
结束看起来像:
EXECUTE dbo.getLocationTypes '<IDList><ID>1</ID><ID>3</ID></IDList>',
'<IDList><ID>200</ID><ID>300</ID><ID>400</ID></IDList>'
答案 1 :(得分:1)
使用大IN
列表并不是一件坏事,但如果列表中有数千个元素,则可能会遇到问题,因为参数列表可能会导致问题。
但基本上另一种方法是加入一些(临时)表。但是,使用该策略需要将数据插入表中,因此除非您可以多次重复使用查询,否则插入过滤数据所涉及的工作将大大超出返回结果的工作量。
这里最好的建议就是查看查询分析器的结果。
使用临时表的第二种方法的示例如下所示。在这里,您可以获得在JOIN中使用索引的好处,但这应该与每个过滤器值的插入成本和使用过滤器函数的代码的复杂性形成对比。 (一个简单的IN
子句由LINQ自动生成,而临时表方法在代码中需要相当多的重复。)
CREATE TABLE vals (v nvarchar(255), inserted DATETIME DEFAULT(getdate()))
SELECT * FROM vals
WHERE v IN ('a', 'aa', 'aaa')
DECLARE @filters TABLE (v varchar(256))
INSERT INTO @filters (v) VALUES ('a')
INSERT INTO @filters (v) VALUES ('aa')
INSERT INTO @filters (v) VALUES ('aaa')
SELECT * FROM vals INNER JOIN @filters f
ON f.v = vals.v
答案 2 :(得分:1)
给出包含字符串和日期时间的某种类型的列表:
public class MyType
{
public Name {get;set;}
public Timestamp {get;set;}
}
SPROC搜索结果填充了List&lt; MyType&gt;我的列表 您还会获得一个字符串列表List&lt; string&gt; myNamesList
var results = myList.Where(r => myNamesList.Contains(r.Name) && myList.Timestamp > someDateTime).ToList();
列表中的结果&lt; MyType&gt;过滤后的结果。
答案 3 :(得分:1)
如果您使用的是SQLServer 2008,另一种方法可能是将.net DataTable传递给TSQL。有关详细信息:http://www.sommarskog.se/arrays-in-sql-2008.html#DataTable