使用实体框架插入后更新多列

时间:2019-08-22 14:26:46

标签: c# sql-server 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
  

注意:有关触发器内部的逻辑缺陷,我将参考Create an incremental number with year and month without updating the entire table using a trigger on Database Administrators 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);

1 个答案:

答案 0 :(得分:0)

我发现它无需编写2 nd 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; }
}
相关问题