使用Dapper.net执行合并操作

7
我们在ASP.net MVC 5应用程序中使用Dapper.net作为数据层。其中一个操作需要使用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语句吗?

我找不到任何关于这个的资料,也不清楚在使用Dapper.net时使用MERGE的最佳方法是什么?

2个回答

12

刚发现你可以像我在这里的.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);
        }
    }
}

1
它针对每个OrderDetails执行不同的合并命令。 - ehsan

4
未经测试,但这应该可以解决问题:
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在做什么? - niico
Dapper没有特定的合并方法。虽然我没有尝试过,但有一个商业库叫做Dapper Plus,声称支持合并。 - Jan Sommer
如果可以的话那就太好了,但是由于每个支持合并的数据库都有自己的语法,而且Dapper希望支持所有这些数据库,所以我想这需要相当多的工作。https://github.com/StackExchange/Dapper#user-content-will-dapper-work-with-my-db-provider - Jan Sommer
以上没问题 - 你知道HOLDLOCK在Dapper中是否能正常工作吗? - niico
我不认为有什么问题。Dapper在将SQL发送到数据库之前不会更改它。 - Jan Sommer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接