Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Database default value being used when explicit value set #16042

Closed
adrianwright109 opened this issue Jun 12, 2019 · 2 comments
Closed

Database default value being used when explicit value set #16042

adrianwright109 opened this issue Jun 12, 2019 · 2 comments

Comments

@adrianwright109
Copy link
Contributor

Not sure whether this is a known issue or not. But it seems that when inserting a new entity into the database if the StatusId int property has an explicit value of 0, this value is ignored and the database default value of 1 is used instead.

I have read this maybe due to the fact that the CLR type defaults are ignored so for an int a 0 value would be ignored therefore it uses the database default.

Updating the entity seems to be unaffected.

I don't want to have to change my entity property to int? as it always has a value.

Has this issue been fixed ?

I have an Entity as follows:

public class FuelGroup
{
    public int Id { get; set; }

    public string ConcurrencyStamp { get; set; }
    
    public string Description { get; set; }

    public string ShortDesc { get; set; }

    public int StatusId { get; set; }
}
public enum StatusEnums
{
    Inactive = 0,
    Active = 1,
    Other = 2
}
public class DataContext : DbContext, IDataContext
{
    private const string SQL_NEWID_FUNCTION = "(newid())";

    public DataContext(DbContextOptions<DataContext> options)
        : base(options)
    {
    }
        
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        
        modelBuilder.Entity<FuelGroup>(ConfigureFuelGroup);
    }
    
    private void ConfigureFuelGroup(EntityTypeBuilder<FuelGroup> builder)
    {
        builder.Property(p => p.Id)
            .IsRequired()
            .ValueGeneratedOnAdd()
            .UseSqlServerIdentityColumn();

        builder.HasKey(p => p.Id);

        builder.Property(e => e.ConcurrencyStamp)
            .IsRequired()
            .HasDefaultValueSql(SQL_NEWID_FUNCTION);

        builder.Property(p => p.Description)
            .HasMaxLength(FuelGroupValidators.DescriptionMaxLength)
            .IsRequired();

        builder.Property(p => p.ShortDesc)
            .HasMaxLength(FuelGroupValidators.ShortDescMaxLength)
            .IsRequired();

        builder.Property(p => p.StatusId)
            .IsRequired()
            .HasDefaultValue((int)StatusEnums.Active);
    }
}

CREATE TABLE [FuelGroups] (
[Id] [int] IDENTITY(1,1) NOT NULL,
[ConcurrencyStamp] nvarchar NOT NULL DEFAULT (NEWID()),
[Description] nvarchar NOT NULL,
[ShortDesc] nvarchar NOT NULL,
[StatusId] [int] NOT NULL DEFAULT(1)
)

Further technical details

EF Core version:
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.4" />

Database Provider:
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.4" />

Operating system:
Windows 7

IDE:
Visual Studio 2019 16.1.2

@ajcvickers
Copy link
Member

@adrianwright109 To use generated values for keys there needs to be a "sentinel" to indicate that the generated value should be used. The CLR default is this sentinel.

If the key values are not generated (i.e. ValueGeneratedNever), then any value can be used, including the CLR default.

Issue #701 is about providing even greater control over when to generate a value and when not to.

@mindtheappsrl
Copy link

I have the same problem, but not for all databases, here's my scenario:
I have two databases on Azure SQL Databases, with one database the Scaffold command recognizes all the default values (newid,getdate etc ), with the other DB (same configuration of the previous) the scallod command replace hasdefaultvaluesql (on the newID) with ValueGeneratedNever();

here's the modelbuilder version (I tried with different version but the result is the same)
modelBuilder.HasAnnotation("ProductVersion", "2.2.4-servicing-10062");

I use the same scaffold command string (with different users, but with the same privileges), here's the command

Scaffold-DbContext "Server=xxxx;Initial Catalog=yyyy;Persist Security Info=False;User ID=TC_USER;Password=zzzz;MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=False;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir DB -force

I tried also with MultipleActiveResultSets=false, but the result is the same

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants