question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Updated computed columns property may be inverted with INSTEAD OF triggers

See original GitHub issue

EF Core version: 5.0.7 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: .NET 5.0 Operating system: W10 x64 IDE: VS 2019 16.10.4


Hello,

I’m having an issue with INSTEAD OF triggers and computed columns on SQL Server.

Here is a sample model :

public class MyTable
{
    public long Identifier { get; set; }
    public string NotComputedColumn { get; set; }
    public string ComputedColumn1 { get; set; }
    public string ComputedColumn2 { get; set; }
}

public class MyContext : DbContext
{
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<MyTable>(entity =>
            {
                entity.ToTable(nameof(MyTable));

                entity.HasKey(e => e.Identifier);

                entity.Property(e => e.ComputedColumn1 )
                    .HasComputedColumnSql();

                entity.Property(e => e.ComputedColumn2 )
                    .HasComputedColumnSql();
            });

            base.OnModelCreating(modelBuilder);
        }
}

When using computed columns with HasComputedColumnSql on a table, EF Core add the columns to a generated SELECT query after the INSERT statement. By example :

exec sp_executesql N'SET NOCOUNT ON;
INSERT INTO [Table] ([NotComputedColumn])
VALUES (@p0);
SELECT [Identifier], [ComputedColumn1], [ComputedColumn2]
FROM [Contact]
WHERE @@ROWCOUNT = 1 AND [Identifier] = scope_identity();
',N'@p0 nvarchar(4000)',@p0='A value'

EF have this logic :

  • insert data
  • select keys and computed columns
  • take the first results set of the data reader
  • update the POCO with readed data

All my tables have INSTEAD OF INSERT triggers like this :

CREATE TRIGGER [dbo].[MyTableInsteadOfInsert] ON [dbo].[MyTable] INSTEAD OF INSERT AS 
BEGIN

    CREATE TABLE #TempTable (
        [Identifier] BIGINT
        ,[ComputedColumn1] VARCHAR(100)
        ,[ComputedColumn2] VARCHAR(100)
    )

    --Pre insert SQL code
	
    INSERT INTO MyTable
    (
        NotComputedColumn 
    )
    OUTPUT
        inserted.Identifier
        ,inserted.ComputedColumn1 
        ,inserted.ComputedColumn2
    INTO
        #TempTable

    --This statement is the one readed by EF Core since it will be the first result set in the data reader. The generated SELECT by EF is replaced by this one.
    SELECT 
        t0.Identifier
        ,t0.ComputedColumn1 --NOTE : Changing column order is causing the described issue, see below
        ,t0.ComputedColumn2
    FROM
        #TempTable AS t0

    --Post insert code

END

As you can see, the trigger make a similar SELECT statement just after the INSERT INTO. I do this in order to be sure that EF read this result set and not another one that may be generated by another SELECT statement in the post insert code section.

My issue is that EF Core do not use the column name when reading the select results, EF use the result columns order. This lead to an issue if in my SELECT statement the ComputedColumn2 column is projected prior the ComputedColumn1 column.

It seams that EF Core use the alphabetic order so it works if my trigger respect this order too but this is a breaking changes from the Entity Framework V4 (yes, I know, it’s old…).

Is there any chance you can modify this ?

Thanks a lot

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
ajcvickerscommented, Aug 13, 2021

Note from triage: discussed with team and agreed that this change is by-design.

@JeremyLikness This could be something to mention in the porting guide.

0reactions
Benjamin-DAGUEcommented, Aug 4, 2021

I understand the change was made for optimisation and yes I can change the order of the columns in the trigger because this changes will not break currently working EF Framework V4 but since there is no warning or error, this could lead to potential bugs in production if some triggers are not modified and EF Core compliants.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Instead Of Trigger to pseudo-update computed column
I've created a function to return the computed status on the parent table, and that's working fine. I also created an INSTEAD OF...
Read more >
Can altering a computed column definition cause an ...
An alter to the table is not an update to the data, so a trigger defined to fire on update will not fire...
Read more >
Using Triggers to Replace Scalar UDFs on Computed ...
I replaced such a table with a view (with the same name), plus another table to hold the non-computed columns, plus an INSTEAD...
Read more >
Chapter 9: Computed Fields And Onchanges
Note that the inverse method is called when saving the record, while the compute method is called at each change of its dependencies....
Read more >
Database PL/SQL Language Reference
An INSTEAD OF trigger can read OLD and NEW values, but cannot change them. An INSTEAD OF trigger with the NESTED TABLE clause...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found