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

发布于 2024-10-26 11:22:13 字数 483 浏览 2 评论 0原文

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

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

I have an in memory List of objects. I want to check if each one exists in a database and if not, set a bool property on that object to true.

Object

class Part
    {
        public bool NewPart { get; set; }
        public string PartNumber { get; set; }
        public string Revision { get; set; }
        public string Description { get; set; }
    }

List contains the collection of parts. For each part, if it exists in the database then NewPart should be set to FALSE, else TRUE. I'm looking for the most efficient way to do this as there are likely to be hundred of parts so I'm thinking that running a SQL query for each part may not be the most efficient method.

Ideas on the best way to achieve this appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

洒一地阳光 2024-11-02 11:22:13

这取决于您使用的 ORM,但使用 Linq2Sql,您可以使用如下查询:

var query = from p in db.parts
            where myList.Contains(p.PartNumber)
            select p.PartNumber;

然后您可以使用返回的 IEnumerable 来设置 newPart 字段

作为替代方案,如果您的最终目标是执行Upsert 类型操作,然后查看此问题及其答案 在 SQL Server 上插入更新存储过程(需要 SQL 级别实现,而不是 linq)

It depends on which ORM you are using, but with Linq2Sql you can use a query like:

var query = from p in db.parts
            where myList.Contains(p.PartNumber)
            select p.PartNumber;

You can then use the IEnumerable returned to set your newPart field

As an alternative, if your ultimate goal is to do an Upsert type action, then check out this question and its answers Insert Update stored proc on SQL Server (needs SQL level implementation, not linq)

土豪我们做朋友吧 2024-11-02 11:22:13

以下只会访问数据库一次。

   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 .... )

因此如果零件列表有 100 个左右,则这应该有效,但如果零件列表超过 2100 个,则无效。

The following will only hit the database once.

   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);

Note, the generated sql could very well be something like

SELECT PartNumber
FROM Parts Where PartNumber in (@p0, @p1, @p2, @p3 .... )

so this should work if the parts list of a hundred or so, but not if it is over 2100.

九局 2024-11-02 11:22:13

这是最有效的方法取决于实际数据的情况之一。

第一个从数据库中获取所有partNum:

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 是 List <首先获得了 code>parts ,这里我们不是获取列表,而是获取字典,这使得更有效地检索我们想要的内容。然而,如果我们无论如何都要以列表的形式获取 parts ,那么我们在这里就无法真正获得收益,因为我们首先需要比迭代列表更多的精力来构建字典。

This is one of those cases where the most efficient approach depends upon the actual data.

The first obtains all partNums from the database:

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);

The second queries the database with the relevant 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);

The former will be more efficient above a certain number of rows in the database, and less efficient above it, because the latter takes a longer time to build a more complicated query, but the former returns everything.

Another factor is the percentage of hits expected. If this number is relatively low (i.e. only a small number of the parts in the list will be in the database) then it could be more efficient to do:

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;

Where partsSource is the means by which the List parts was obtained in the first place, here instead of obtaining a list, we obtain a dictionary, which makes for more efficient retrieval of those we want. However, it we're going to obtain parts as a list anyway, then we can't really gain here, as we use slightly more effort building the dictionary in the first place, than iterating through the list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文