Skip to content

As of EF7 Scaffold-DbContext doesn't handle columns computed from a function #30999

@jkeslinke

Description

@jkeslinke

Per the EF7 breaking changes I understand Computed Columns and tables with Triggers need to be specially configured. Using Scaffold-DbContext handles the triggers and computed columns in most cases.

The one case we've run into that doesn't seem to be handles is a Computed Column that is generated from a function. i.e.

CREATE TABLE [dbo].[SomeTable](
        ...
	[totalCost]  AS ([dbo].[fn_calculateCost]([Id])),
        ...
)

We are scaffolding it like this:

Scaffold-DbContext "ConnectionString" Microsoft.EntityFrameworkCore.SqlServer -StartupProject Infrastructure.Data -Project Infrastructure.Data -OutputDir Scheduling -Context SchedulingContext -Tables SomeTable -Force -NoOnConfiguring -NoPluralize

Which generates this:


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
		modelBuilder.Entity<SomeTable>(entity =>
        {
            ...
            entity.Property(e => e.TotalCost)
                .HasComputedColumnSql("([dbo].[fn_calculateCost]([Id]))", false)
                .HasColumnType("decimal(19, 4)")
                .HasColumnName("totalUnits");
			...
        });
		
        OnModelCreatingPartial(modelBuilder);
    }

The exception is: Column 'inserted.totalCost' cannot be referenced in the OUTPUT clause because the column definition contains a subquery or references a function that performs user or system data access. A function is assumed by default to perform data access if it is not schemabound. Consider removing the subquery or function from the column definition or removing the column from the OUTPUT clause.

The only way I have determined to work around this for now is to manually add "Triggers" to the EF Context Mapping for the functions used by the computed columns (per this post):

        partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<SomeTable>(entity =>
            {
                entity.ToTable(tbl => tbl.HasTrigger("([dbo].[fn_calculateCost]([Id]))"));
            });
        }

But this solution is not ideal. Not only does it only solve this singular issue, leaving other potential issues out there, but if we ever change the column/function we would have to remember to manually go in and update this line.

Ideally, it would be nice if the Scaffold-DbContext command picked up this change like it does so well for everything else.

EF Core version: 7.0.5
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 6.0
Operating system: Windows 10/Server 2016
IDE: Visual Studio 2022 17.4.5

Thank you,
Jeff

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions