我有一个内存列表中的对象。我想检查数据库中是否存在每个数据库,如果不存在,请将该对象的bool属性设置为true。
对象
class Part
{
public bool NewPart { get; set; }
public string PartNumber { get; set; }
public string Revision { get; set; }
public string Description { get; set; }
}
列表包含部分集合。对于每个部分,如果它存在于数据库中,则NewPart应设置为FALSE,否则为TRUE。我正在寻找最有效的方法,因为可能有数百个部分,所以我认为为每个部分运行SQL查询可能不是最有效的方法。
关于实现这一目标的最佳方式的想法。
答案 0 :(得分:1)
这取决于您使用的是哪个ORM,但使用Linq2Sql,您可以使用如下查询:
var query = from p in db.parts
where myList.Contains(p.PartNumber)
select p.PartNumber;
然后,您可以使用返回的IEnumerable
来设置newPart字段
作为替代方案,如果您的最终目标是执行Upsert
类型操作,那么请查看此问题及其答案Insert Update stored proc on SQL Server(需要SQL级别实现,而不是linq)
答案 1 :(得分:1)
以下内容只会打到数据库一次。
var myList = (from r in parts select r.PartNumber).ToList();
var existingParts = (from r in dc.Parts
where myList.Contains(r.PartNumber) select r.PartNumber).ToList();
foreach(var r in parts)
r.NewPart = existingParts.Contains(r.PartNumber);
注意,生成的sql很可能就像
SELECT PartNumber
FROM Parts Where PartNumber in (@p0, @p1, @p2, @p3 .... )
所以这应该适用于零件清单一百左右,但如果超过2100则不行。
答案 2 :(得分:0)
这是最有效的方法取决于实际数据的情况之一。
第一个从数据库中获取所有partNums:
HashSet<int> partNums = new HashSet<int>(from p in GetTable<DBPart> select p.PartNumber);
foreach(var p in parts)
p.NewPart = partNums.Contains(p.PartNumber);
第二个使用相关的partNumbers查询数据库:
HashSet<int> partNums = new HashSet<int>(
from p in GetTable<DBPart> where (from mp in parts select mp.PartNumber).Contains(p.PartNumber) select p.PartNumber);
foreach(var p in parts)
p.NewPart = partNums.Contains(p.PartNumber);
前者在数据库中的某些行数之上会更有效,而在它之上的效率会更低,因为后者需要更长的时间来构建更复杂的查询,但前者会返回所有内容。
另一个因素是预期命中率。如果这个数字相对较低(即列表中只有少数部分将在数据库中),那么它可能更有效:
Dictionary<int, Part> dict = partsSource.ToDictionary(p => p.PartNumber, p);
foreach(int pn in
from p in GetTable<DBPart> where (from kv in dict select kv.Key).Contains(p.PartNumber) select p.PartNumber);
dict[pn].NewPart = true;
其中partsSource
是首先获取列表parts
的方式,而不是获取列表,我们获取字典,这样可以更有效地检索我们想要的字典。但是,我们无论如何都会获得parts
作为列表,然后我们无法真正获得这里,因为我们首先使用更多的努力来构建字典,而不是遍历列表。