Skip to content

Insert default value for Shadow Property #13462

New issue

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

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

Already on GitHub? # to your account

Closed
jasonycw opened this issue Oct 2, 2018 · 6 comments
Closed

Insert default value for Shadow Property #13462

jasonycw opened this issue Oct 2, 2018 · 6 comments

Comments

@jasonycw
Copy link

jasonycw commented Oct 2, 2018

Insert default value with shadow property not working as expected

Steps to reproduce

Was hoping to use HasDefaultValue to insert some default value to db without adding it to our entity.
But it seems not working and we need to set the current value before save.

Here is some sample code

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

public class SqlDbContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder
            .UseSqlServer(@"Server=.;Database=local;Trusted_Connection=True;");

    protected override void OnModelCreating(ModelBuilder builder) =>
        builder.Entity<Account>(m =>
        {
            m.ToTable("users", "dbo");
            m.HasKey(x => x.Id);
            m.Property(x => x.Id).HasColumnName("id");

            // Shadow properties
            m.Property<string>("some_out_of_domain_column")
                .HasDefaultValue("some_out_of_domain_data");
        });
}

public class Program
{
    public static async Task Main()
    {
        using (var context = new SqlDbContext())
        {
            var account = new Account();
            var entry = context.Add(account);
            // This is what we finally did
            //entry.Property("some_out_of_domain_column").CurrentValue = "some_out_of_domain_data";
            await context.SaveChangesAsync(CancellationToken.None);
        }
    }
}

Further technical details

EF Core version: 2.1.4
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10
IDE: Visual Studio 2017 15.8.5

@ajcvickers
Copy link
Contributor

@jasonycw HasDefaultValue is for specifying the default value to configure as a constraint on the column in the database, which can then be applied using migrations. If you are mapping this to an existing column, then it won't have any affect. Having the ability to set a client-side default may be a useful addition--we will discuss. For now, setting it in SaveChanges seems like a good workaround.

@ajcvickers
Copy link
Contributor

@divega to find dupe
@ajcvickers to try a value generator

@smitpatel
Copy link
Contributor

Duplicate of #11001

@smitpatel smitpatel marked this as a duplicate of #11001 Oct 4, 2018
@ajcvickers
Copy link
Contributor

@jasonycw It was pointed out that this can actually be done today with a value generator. For example:

public class ConstantValueGenerator : ValueGenerator<string>
{
    public override string Next(EntityEntry _) => "some_out_of_domain_data";

    public override bool GeneratesTemporaryValues => false;
}
modelBuilder
    .Entity<Blog>()
    .Property<string>("some_out_of_domain_column")
    .HasValueGenerator<ConstantValueGenerator>();

This will set the value for the shadow property on every new entity before it is inserted.

@jasonycw
Copy link
Author

jasonycw commented Oct 5, 2018

@ajcvickers Thanks, this is a good idea to group the default values in one place.

One more similar issue we want to report too is about HasDefaultValueSql or HasComputedColumnSql

m.Property("_email")
   .HasColumnName("email");
m.Property<string>("another_email_column")
   .HasDefaultValueSql("[email]");
m.Property<string>("is_gmail")
   .HasComputedColumnSql("IIF([email] LIKE '%@gmail.com', 1, 0)");

The another_email_column and is_gmail will still be NULL when we add entities to the DB.
I assume it is the same as HasDefaultValue where our understanding was incorrect.

Any suggestion on how to map shadow property to be the same value as another column or do some logic?
Or have some default behavior using the entity?

@ajcvickers
Copy link
Contributor

@jasonycw Overriding SaveChanges is probably your best bet for that at the current time.

@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
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

3 participants