Linq - 如何检查数据库中是否存在对象

时间:2011-03-26 12:20:12

标签: linq

我有一个内存列表中的对象。我想检查数据库中是否存在每个数据库,如果不存在,请将该对象的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查询可能不是最有效的方法。

关于实现这一目标的最佳方式的想法。

3 个答案:

答案 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作为列表,然后我们无法真正获得这里,因为我们首先使用更多的努力来构建字典,而不是遍历列表。