将本地实体合并到跳过主键的表中(linq2db)

时间:2017-11-16 12:47:00

标签: sql-server linq2db

我想使用linq2db将本地实体列表合并到一个表中(如果它们已经不存在)。

我尝试执行以下操作:

var recordsConvertedToOrders = reportRecords.Select(i =>
{
    // some predefined conversion
    var order = mapper.Map<Order>(i);
    order.Created = DateTime.Now;
    return order;
});


using (var db = new DataConnection("StuckOrders"))
{
    var count = await db.GetTable<Order>()
        .Merge()
        .Using(recordsConvertedToOrders)
        .On((t, s) => t.OrderlineID == s.OrderlineID)
        .InsertWhenNotMatched()
        .MergeAsync();
}

给了我这个例外:

Unhandled Exception: System.Data.SqlClient.SqlException: 
Violation of PRIMARY KEY constraint 'PK_Order'. 
Cannot insert duplicate key in object 'dbo.Order'. 
The duplicate key value is (0).
The statement has been terminated.

这是因为生成了以下SQL。

(注意0已为Id传递,然后将INSERT插入表中。)

-- StuckOrders SqlServer.2012 (asynchronously)
SET IDENTITY_INSERT [dbo].[Order] ON
MERGE INTO [dbo].[Order] [Target]
USING
(
        VALUES
        (0,9369660,13869511,N'BP1328147327',NULL,NULL,NULL,'2017-11-08T23:08:54','2017-11-08','2017-11-08T23:08:00',18302384,N'LinkedProductToProductContent',NULL,'2017-11-16T09:24:14.300',0,0,0,0,0,0,0,N'3. orderitem (FFApi) not in FulfilmentOrderlines',15829191,N'Windows Editor',0,NULL,NULL,'2017-11-16T13:28:10.866',NULL),
        (0,9308332,13792138,N'NO1320410131',NULL,NULL,NULL,'2017-11-04T22:58:49','2017-11-04','2017-11-04T22:57:00',18193864,N'FailedFinalizerJob',NULL,'2017-11-16T09:24:14.300',0,0,0,0,0,0,0,N'1. orderitem not in fulfilmentflow',15745587,N'Prints Editor',0,NULL,NULL,'2017-11-16T13:28:10.896',NULL)
) [Source] ([c0], [c1], [c2], [c3], [c4], [c5], [c6], [c7], [c8], [c9], [c10], [c11], [c12], [c13], [c14], [c15], [c16], [c17], [c18], [c19], [c20], [c21], [c22], [c23], [c24], [c25], [c26], [c27], [c28])
ON ([Target].[OrderlineID] = [Source].[c10])

WHEN NOT MATCHED THEN
INSERT
(
        [Id],
        [OrderId],
        [OrderItemId],
        [OrderItemCode],
        [OrderCode],
        [CopyItemCode],
        [ProductionTicketID],
        [OrderDateTime],
        [OrderDate],
        [UploadEndDateTime],
        [OrderlineID],
        [ProductContentStatusName],
        [ProductContentStatusDate],
        [Date],
        [check_notIn_FulfillmentFlow],
        [check_notIn_PlantFromOrderDomain],
        [check_notIn_Fulfillment],
        [check_notIn_PlantFromFulfillment],
        [check_Vouchers],
        [check_ExternalVendors],
        [check_notIn_Waiting],
        [CheckDescription],
        [ProductContentID],
        [EditorName],
        [Resolved],
        [FixOrdersJira],
        [RootCauseJira],
        [Created],
        [Updated]
)
VALUES
(
        [Source].[c0],
        [Source].[c1],
        [Source].[c2],
        [Source].[c3],
        [Source].[c4],
        [Source].[c5],
        [Source].[c6],
        [Source].[c7],
        [Source].[c8],
        [Source].[c9],
        [Source].[c10],
        [Source].[c11],
        [Source].[c12],
        [Source].[c13],
        [Source].[c14],
        [Source].[c15],
        [Source].[c16],
        [Source].[c17],
        [Source].[c18],
        [Source].[c19],
        [Source].[c20],
        [Source].[c21],
        [Source].[c22],
        [Source].[c23],
        [Source].[c24],
        [Source].[c25],
        [Source].[c26],
        [Source].[c27],
        [Source].[c28]
)
;
SET IDENTITY_INSERT [dbo].[Order] OFF

这是由linq2db生成的Order模型:

[Table(Schema="dbo", Name="Order")]
public partial class Order
{
    [Column(), PrimaryKey,  Identity] public long Id { get; set; } // bigint
    ...

我希望在Id SQL中跳过MERGE,以便可以将它们生成为正常的增量标识值。

我最终指定了要手动插入的字段(我不喜欢它,因为它复制了我们的AutoMapper映射):

using (var db = new DataConnection("StuckOrders"))
{
    var count = await db.GetTable<Order>()
        .Merge()
        .Using(reportRecords)
        .On((t, s) => t.OrderlineID == s.OrderLineId)
        .InsertWhenNotMatched(s => new Order
        {
            OrderId = s.OrderId,
            OrderItemId = s.OrderItemId,
            OrderItemCode = s.OrderItemCode,
            //OrderCode = s.OrderCode,
            ProductionTicketID = s.ProductionTicketId,
            OrderDateTime = s.OrderDateTime,
            OrderDate = s.OrderDate,
            UploadEndDateTime = s.UploadEndDateTime,
            OrderlineID = s.OrderLineId.Value,
            ProductContentStatusName = s.ProductContentStatusName,
            ProductContentStatusDate = s.ProductContentStatusDate,
            Date = s.Date,
            CheckNotInFulfillmentFlow = s.check_notIn_FulfillmentFlow,
            CheckNotInPlantFromOrderDomain = s.check_notIn_PlantFromOrderDomain,
            CheckNotInFulfillment = s.check_notIn_Fulfillment,
            CheckNotInPlantFromFulfillment = s.check_notIn_PlantFromFulfillment,
            CheckVouchers = s.check_Vouchers,
            CheckExternalVendors = s.check_ExternalVendors,
            CheckNotInWaiting = s.check_notIn_Waiting,
            CheckDescription = s.CheckDescription,
            ProductContentID = s.ProductContentID,
            EditorName = s.EditorName,
            Created = DateTime.Now,
        })
        .MergeAsync();
}

如何让第一个代码段按预期工作?

0 个答案:

没有答案