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

Assignment to inherited field, bypassing an hiding field #35643

Open
Alexcrazy42 opened this issue Feb 16, 2025 · 2 comments
Open

Assignment to inherited field, bypassing an hiding field #35643

Alexcrazy42 opened this issue Feb 16, 2025 · 2 comments

Comments

@Alexcrazy42
Copy link

Question

Hello! I have a question about assignment to class hierarchy in EF Core.

Image

This class inherited by simple class Entity, that just add generic Identifier to inheritor classes. I accidentally hide the field from the parent by redefinition without keyword new.

Then I fetch data with EF I have this:

Image

That is, I have 2 fields: from parent and from class.

And then I make some updates EF take field from class (Guid.Empty):

Image

In fluent configuration then I have hiding field, exactly this field detect as key.

Image

Naturally, removing Id from inheritor solve this.
I thought it wasn't a bug.
But, I have question about how EF detect what field in hierarchy need to fill. Please, give me hints where the part is located with filling fields from the inheritance hierarchy.

Your code

Stack traces


Verbose output


EF Core version

9.0.0

Database provider

Npgsql.EntityFrameworkCore.PostgreSQL

Target framework

.NET 8.0

Operating system

Windows 11

IDE

Rider 2024

@Alexcrazy42 Alexcrazy42 changed the title Assignment to an inherited field, bypassing an overridden field Assignment to an inherited field, bypassing an hiding field Feb 16, 2025
@Alexcrazy42 Alexcrazy42 changed the title Assignment to an inherited field, bypassing an hiding field Assignment to inherited field, bypassing an hiding field Feb 16, 2025
@maumar
Copy link
Contributor

maumar commented Feb 17, 2025

I'm unable to reproduce this. Please provide full standalone repro that shows the issue. When trying in my environment I'm seeing derived property being used both for update and for query.

Here is what I tried - you can modify this code in such a way that it reproduces the issue

    [ConditionalFact]
    public async Task Repro123()
    {
        using (var ctx = new MyContext())
        {
            await ctx.Database.EnsureDeletedAsync();
            await ctx.Database.EnsureCreatedAsync();

            var e = new UserSetting { Id = Guid.NewGuid(), Name = "foo" };
            ctx.Set<UserSetting>().Add(e);
            await ctx.SaveChangesAsync();
        }



        using (var ctx = new MyContext())
        {
            var result = await ctx.Set<UserSetting>().FirstAsync();

            result.Name = "bar";

            await ctx.SaveChangesAsync();
        }


        using (var ctx = new MyContext())
        {
            var result = await ctx.Set<UserSetting>().FirstAsync();
        }

    }

    public class MyContext : DbContext
    {
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<UserSetting>().HasKey(x => x.Id);
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Repro35643;Trusted_Connection=True;MultipleActiveResultSets=true")
                .EnableSensitiveDataLogging();
        }
    }

    public class Entity<T>
    {
        public T Id { get; set; }
    }

    public class UserSetting : Entity<Guid>
    {
        public new Guid Id { get; set; }
        public string Name { get; set; }
    }

@Alexcrazy42
Copy link
Author

all you need to reproduce problem: delete new on this line in class UserSetting: public new Guid Id { get; set; }

line should be: public Guid Id { get; set; }

I understand, that it is a source of problem, but I want to understand why EF with this EntityConfiguration:
modelBuilder.Entity<UserSetting>().HasKey(x => x.Id);

perceive Id from inheritor, but then fetch data from DB, fill id from base class:

Image

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