簡體   English   中英

使用實體框架插入后更新多列

[英]Update multiple columns after insert using Entity Framework

我在表上創建了一個數據庫觸發器,該觸發器將在插入后更新表中的字段。 當使用EF插入時,我將獲得ID和編號。 在數據庫上,我創建了以下代碼:

create table Things (
    ID int primary key identity not null,
    Number nvarchar(20)
);

create trigger UpdateThingsNumberTrigger on Things
after insert
as
begin

    declare @month nvarchar(2);
    select @month = cast(month(getdate()) as nvarchar(2));

    declare @code nvarchar(15);
    select @code = cast(year(getdate()) as nvarchar(4)) + 
        '.' + 
        replicate('0', 2 - len(@month)) + 
        @month + 
        '.';

    declare @max nvarchar(20);
    select @max = t.ID
    from Things t
    where ID like @code + '%';

    with CTE_UPD as 
    (
        select 
            replicate('0', 
                4 -
                len(cast(coalesce(cast(right(@max, 4) as int), 0) + row_number() over (order by ins.ID) as nvarchar(4)))) + 
                cast(coalesce(cast(right(@max, 4) as int), 0) + row_number() over (order by ins.ID) as nvarchar(4)) as NextNo, 
            ID
        from Things ins
    )   
    update Things
    set Number = @code + NextNo 
    from Things t inner join CTE_UPD ins on ins.ID = t.ID;

end

注意:對於觸發器內部的邏輯缺陷,我將參考在數據庫管理員SE上使用觸發器創建帶有年份和月份的增量編號,而不使用整個觸發器來更新整個表

我的代碼的這一部分工作正常,而忽略了觸發器內部的邏輯缺陷……我將嘗試解決的問題是,當我從Entity Framework中向我的表中插入東西時(首先是數據庫)。 有我的代碼和輸出:

using (Database db = new Database())
{
    Thing thing = new Thing(); // --> just an empty constructor.
    db.Entry(thing).State = EntityState.Added;
    await db.SaveChangesAsync();

    Console.WriteLine($"ID = {thing.ID}");
    Console.WriteLine($"Number = {thing.Number}");
}

// Output:
// ID = 1
// Number = 

在后台,EF在調用SaveChangesAsync()時在服務器上執行以下代碼:

INSERT [dbo].[Things]([Number])
VALUES (NULL)

SELECT [ID]
FROM [dbo].[Things]
WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity()

現在,EF可以更新C#對象中的ID。 但是如何在關閉using塊之前不使用下面的代碼就可以得到數字?

Thing recentlyInsertedThing = await db.Things.FindAsync(thing.ID);

我發現它無需編寫第二個 select語句即可獲取ID和Number。 這是我的代碼:

using (Database db = new Database())
{
    Thing thing = new Thing();
    string sql = @"insert into Things() 
                    values ();
                    select ID, Number
                    from Things
                    where @@rowcount > 0 and ID = scope_identity();";

    KeyMapper recentlyRecevedKeys = await db
        .Database
        .SqlQuery<KeyMapper>(sql)
        .FirstAsync();

    thing.ID = recentlyRecevedKeys.ID;
    thing.Number = recentlyRecevedKeys.Number;  
}

// Nested class
private class KeyMapper
{
    public int ID { get; set; }
    public string Number { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM