I've created a database trigger on my table that updates a field in the table after an insert. When doing an insert using EF I'll get the ID and the number. On the database I've created this code:
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
Note: For the logical flaw inside the trigger, I'll refer to Create an incremental number with year and month without updating the entire table using a trigger on Database Administrators SE.
This part of my code works fine, ignoring the logical flaw inside the trigger… The problem I'll try to solve in this question, is when I insert a thing in my table from Entity Framework (database first). There is my code and the output:
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 =
In the background EF is doing this code on the server when calling SaveChangesAsync()
:
INSERT [dbo].[Things]([Number])
VALUES (NULL)
SELECT [ID]
FROM [dbo].[Things]
WHERE @@ROWCOUNT > 0 AND [ID] = scope_identity()
Now can EF update the ID in the C# object. But how could I get the number without using code below before closing the using block?
Thing recentlyInsertedThing = await db.Things.FindAsync(thing.ID);