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

Optional Owned Entity Type properties don't get set to null on BulkMergeAsync #472

Open
meinsiedler opened this issue Mar 1, 2022 · 1 comment
Assignees

Comments

@meinsiedler
Copy link

meinsiedler commented Mar 1, 2022

Description

We have an optional Owned Entity Type configured for an entity. Example: User has an optional owned entity type Address. We use BulkMergeAsync to insert/update new User entities into the database.

When we set the optional Address property to null in the C# objects, the values aren't updated and won't get set to null in the database when using BulkMergeAsync.

Fiddle or Project (Optional)

The following sample program shows the behavior:

  1. We insert a new user where Address properties and the optional Info property are set to some values using BulkMergeAsync.
  2. We update the existing user: We set Address and Info to null and call BulkMergeAsync again.
  3. Expected behavior: All Address properties and the Info property are set to null.
  4. Actual behavior: The Info property is set to null (as expected) but all Address properties are still set to the original values.
using Microsoft.EntityFrameworkCore;

using (var context = new UserStore())
{
    // Cleanup users for testing
    await context.Users.DeleteFromQueryAsync();
}

using (var context = new UserStore())
{
    var users = new List<User>()
    {
        new User(new Guid("00000000-0000-0000-0000-000000000001"), "Name 1") { Address = new Address("City 1", "Street 1"), Info = "Info 1" },
    };

    await context.BulkMergeAsync(users);
}

Console.WriteLine();
Console.WriteLine("AFTER FIRST BULK MERGE");
Console.WriteLine();

using (var context = new UserStore())
{
    context.Users.ToList().ForEach(Console.WriteLine);

    var users = new List<User>()
    {
        // Setting Info and Address to null
        new User(new Guid("00000000-0000-0000-0000-000000000001"), "Name 1") { Address = null, Info = null },
    };

    await context.BulkMergeAsync(users, opts => opts.IncludeGraph = true);
}

Console.WriteLine();
Console.WriteLine("AFTER FIRST BULK MERGE");
Console.WriteLine();

using (var context = new UserStore())
{
    context.Users.ToList().ForEach(Console.WriteLine); // <-- 'Info' property is correctly set to null but 'Address' (Owned Entity) properties are still set.
}

public class User
{
    public User(
        Guid id,
        string name)
    {
        Id = id;
        Name = name;
    }

    public Guid Id { get; set; }
    public string Name { get; set; }
    public string? Info { get; set; }
    public Address? Address { get; set; }

    public override string ToString()
    {
        return $"Name: {Name}\nInfo: {Info}\nAddress: {Address?.Street} {Address?.City}";
    }
}

public class Address
{
    public Address(
        string street,
        string city)
    {
        Street = street;
        City = city;
    }

    public string Street { get; set; }
    public string City { get; set; }
}

public class UserStore : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer(ConnectionString.Value);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<User>().OwnsOne(u => u.Address);
    }

    public DbSet<User> Users => Set<User>();
}

Output

AFTER FIRST BULK MERGE

Name: Name 1
Info: Info 1
Address: City 1 Street 1

AFTER FIRST BULK MERGE

Name: Name 1
Info:
Address: City 1 Street 1 // <-- here we would expect null values

Further technical details

  • EF version: Microsoft.EntityFrameworkCore.SqlServer 6.0.0
  • EF Extensions version: 6.13.12
  • Database Provider: SQL Server
@JonathanMagnan
Copy link
Member

Hello @meinsiedler ,

At this moment, our library for methods such as BulkMerge doesn't support really well optional Owned.

I will look with my developer if we could do something in the short term.

Best Regards,

Jon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants