我在表上创建了一个数据库触发器,该触发器在插入后更新表中的字段。当使用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);
答案 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; }
}