【问题标题】:Do MERGE using Linq to SQL使用 Linq to SQL 进行 MERGE
【发布时间】:2010-07-06 16:14:09
【问题描述】:

SQL Server 2008 耳鼻喉科 ASP.NET MVC 2.0 Linq-to-SQL

我正在建立一个游戏网站,用于跟踪特定玩家(香椿)击倒特定怪物(boss)的时间。表看起来像:

int ToonId
int BossId
datetime LastKillTime

我使用 3d 派对服务,它可以返回最新信息(卡通、老板、时间)。
现在我想用这些新信息更新我的数据库。
蛮力方法是逐行进行upsert。但它看起来很丑(代码方面),而且可能也很慢。

我认为更好的解决方案是插入新数据(使用临时表?)然后运行 ​​MERGE 语句。

这是个好主意吗?我知道临时表是“最好避免的”。我应该为此操作创建一个永久的“临时”表吗?
还是我应该只读取整个当前集合(最多 100 行),合并并从应用程序中放回?

任何指针/建议都会受到赞赏。

【问题讨论】:

    标签: linq-to-sql merge


    【解决方案1】:

    ORM 是执行批处理操作的错误工具,Linq-to-SQL 也不例外。在这种情况下,我认为您选择了正确的解决方案:将所有条目快速存储在临时表中,然后使用合并执行 UPSERT。

    将数据存储到临时表的最快方法是使用SqlBulkCopy 将所有数据存储到您选择的表中。

    【讨论】:

      【解决方案2】:

      如果您使用的是 Linq-to-SQL,则 upsert 不会那么难看..

      foreach (var line in linesFromService) {
         var kill = db.Kills.FirstOrDefault(t=>t.ToonId==line.ToonId && t.BossId==line.BossId);
         if (kill == null) {
            kill = new Kills() { ToonId = line.ToonId, BossId = line.BossId };
            db.Kills.InsertOnSubmit(kill);
         }
         kill.LastKillTime = line.LastKillTime;
      }
      db.SubmitChanges();
      

      不是艺术品,但比 SQL 更好。另外,只有 100 行,我不会太在意性能。

      【讨论】:

      • 我同意,性能不是问题,所以使用 LINQ 方法而不是丑陋的 SQL
      【解决方案3】:

      看起来像一个直截了当的插入。

      private ToonModel _db = new ToonModel();
      Toon t = new Toon();
      t.ToonId = 1;
      t.BossId = 2;
      t.LastKillTime = DateTime.Now();
      _db.Toons.InsertOnSubmit(t);
      _db.SubmitChanges();
      

      【讨论】:

      • 如果我已经有 Id = 1 的 Toon,它不会给我“重复的 id”吗?
      【解决方案4】:

      要在不先查询记录的情况下进行更新,您可以执行以下操作。它仍然会访问数据库一次以检查记录是否存在但不会拉记录:

      var blob = new Blob { Id = "some id", Value = "some value" }; // Id is primary key (PK)
      
      if (dbContext.Blobs.Contains(blob)) // if blob exists by PK then update
      {
          // This will update all columns that are not set in 'original' object. For
          // this to work, Blob has to have UpdateCheck=Never for all properties except
          // for primary keys. This will update the record without querying it first.
          dbContext.Blobs.Attach(blob, original: new Blob { Id = blob.Id });
      }
      else // insert
      {
          dbContext.Blobs.InsertOnSubmit(blob);
      }
      dbContext.Blobs.SubmitChanges();
      

      请参阅here 了解扩展方法。

      【讨论】:

        猜你喜欢
        • 2017-06-07
        • 1970-01-01
        • 1970-01-01
        • 2011-08-26
        • 2011-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多