【问题标题】:Performing MERGE with Dapper.net使用 Dapper.net 执行 MERGE
【发布时间】:2017-05-02 12:49:26
【问题描述】:

我们将 Dapper.net 用于 ASP.net MVC 5 应用程序中的数据层。

一个操作需要使用 MERGE 命令(如果 TitleID 存在,则更新记录,如果不存在,则插入它) - 如下所示:

MERGE BookInventory bi
USING BookOrder bo
ON bi.TitleID = bo.TitleID
WHEN MATCHED THEN
  UPDATE
  SET bi.Quantity = bi.Quantity + bo.Quantity
WHEN NOT MATCHED BY TARGET THEN
  INSERT (TitleID, Title, Quantity)
  VALUES (bo.TitleID, bo.Title,bo.Quantity);

可以使用 Dapper 将值映射到此 MERGE 语句吗?

我在这方面找不到任何东西,不清楚将 MERGE 与 Dapper.net 结合使用的最佳方法是什么?

【问题讨论】:

    标签: dapper


    【解决方案1】:

    刚刚发现您可以像我在 .NET Fiddle 代码中所做的那样:https://dotnetfiddle.net/e2G3Ho

    下面的代码粘贴

    // @nuget: Dapper -Version 1.60.6
    
    using Dapper;
    using System;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Collections.Generic;
    
    public class Program
    {    
        public class OrderDetail
        {
            public int OrderDetailID { get; set; }
            public int OrderID { get; set; }
            public int ProductID { get; set; }
            public int Quantity { get; set; }
        }
    
        public static void Main()
        {
            string sql = "SELECT * FROM OrderDetails";
            string sql2 = @"MERGE INTO OrderDetails AS TARGET 
                USING (
                VALUES
                    (@OrderDetailID, @OrderID, @ProductID, @Quantity)
                ) AS SOURCE (OrderDetailID, OrderID, ProductID, Quantity)
                ON SOURCE.OrderDetailID = TARGET.OrderDetailID
                WHEN MATCHED THEN
                UPDATE SET Quantity = 666
                WHEN NOT MATCHED THEN
                INSERT (OrderID, ProductID, Quantity)
                VALUES (SOURCE.OrderID, SOURCE.ProductID, SOURCE.Quantity);
                "; 
    
            using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
            {   
                List<OrderDetail> details = new List<OrderDetail> {
                    {new OrderDetail() {OrderDetailID = 1, OrderID = 1024, ProductID = 42, Quantity = 1000} },
                    {new OrderDetail() {OrderDetailID = 9999, OrderID = 10268, ProductID = 42, Quantity = 1000} }
                };
    
                connection.Execute(sql2, details);
                var orderDetails = connection.Query<OrderDetail>(sql).ToList();
    
                FiddleHelper.WriteTable(orderDetails);
            }
        }
    }
    

    【讨论】:

    • 它对每个 OrderDetails 执行不同的合并命令。
    【解决方案2】:

    未经测试,但这应该可以解决问题:

    const string sql = @"
        merge into SomeTable as Target
        using (select @myId AS id) as Source
        on (Target.id = Source.id)
        when matched then
            update set Target.SomeColumn = @myValue
        when not matched by Target then
            insert (SomeColumn) values (@myValue)";
    
    conn.Execute(sql, new { myId = 999, myValue = 123 })
    

    【讨论】:

    • 所以所有 dapper 所做的基本上都是对参数的查找和替换?不关心sql在做什么?
    • Dapper 没有特定的合并方法。没试过,不过有 Dapper Plus,一个声称支持合并的商业库。
    • 如果这样做会很好,但是由于每个支持合并的数据库都有自己的语法,而且 Dapper 想要支持所有这些,我想这需要相当多的工作。 github.com/StackExchange/…
    • 以上内容很好——你也知道 HOLDLOCK 是否应该与 dapper 一起正常工作吗?
    • 我不明白为什么不这样做。 Dapper 在发送到数据库之前不会更改您的 sql。
    猜你喜欢
    • 2020-08-15
    • 2013-10-20
    • 2012-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 2011-12-16
    • 1970-01-01
    相关资源
    最近更新 更多