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

Configuring Property with a string cannot discover private fields from base class #9603

Closed
maciejjarzynski opened this issue Aug 28, 2017 · 1 comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Milestone

Comments

@maciejjarzynski
Copy link

maciejjarzynski commented Aug 28, 2017

At first, I'd like to sorry for maybe non-descriptive-enough title, but I couldn't think of anything better right now ;)
The problem looks like regression, it used to work with EF Core 1.1.2.
When configuring entity property with a string-name (Property("propertyName")) when the given field is a private field in a base class throws an exception in OnModelCreating method.
I've read breaking changes in EF Core 2.0 and also some other articles, but I couldn't find anything mentioning such a change.
The actions that are fixing this behaviour:

  • making that field protected/public
  • declaring type explicitely like Property<string>("propertyName")

Exception message:

System.InvalidOperationException: The property 'date' cannot be added to the type 'Entity' because there was no property type specified and there is no corresponding CLR property or field. To add a shadow state property the property type must be specified.

Stack trace:

   at Microsoft.EntityFrameworkCore.Metadata.Internal.EntityType.AddProperty(String name, Type propertyType, MemberInfo memberInfo, ConfigurationSource configurationSource, Nullable`1 typeConfigurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.EntityType.AddProperty(String name, Type propertyType, ConfigurationSource configurationSource, Nullable`1 typeConfigurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(Property existingProperty, String propertyName, Type propertyType, MemberInfo clrProperty, Nullable`1 configurationSource, Nullable`1 typeConfigurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(String propertyName, Type propertyType, MemberInfo memberInfo, Nullable`1 configurationSource, Nullable`1 typeConfigurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.Property(String propertyName, ConfigurationSource configurationSource)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder.Property(String propertyName)
   at ef_repro.Context.<>c.<OnModelCreating>b__1_0(EntityTypeBuilder`1 e) in c:\...Program.cs:line 17
   at Microsoft.EntityFrameworkCore.ModelBuilder.Entity[TEntity](Action`1 buildAction)
   at ef_repro.Context.OnModelCreating(ModelBuilder modelBuilder) in c:\...\Program.cs:line 13
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__0(Object k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_1(IServiceProvider p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
   at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
   at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.get_DatabaseCreator()
   at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureDeleted()

Steps to reproduce

public class Context : DbContext
    {
        public Context(DbContextOptions options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Entity>(e =>
            {
                e.HasKey(p => p.Id);
                e.Ignore(p => p.Date);
                e.Property("date");
            });

            base.OnModelCreating(modelBuilder);
        }
    }

    public class Entity : EntityBase
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    public class EntityBase
    {
        private string date;

        public DateTime Date
        {
            get { return DateTime.Parse(this.date); }
            set { this.date = value.ToString(); }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var ctx = new Context(new DbContextOptionsBuilder<Context>().UseInMemoryDatabase("test_db").Options);
            ctx.Database.EnsureDeleted();
            ctx.Database.EnsureCreated();

            ctx.Set<Entity>().Add(new Entity() { Date = DateTime.Now });
            ctx.SaveChanges();
            var e = ctx.Set<Entity>().FirstOrDefault();            
        }
    }

Further technical details

EF Core version: 2.0.0
Database Provider: (e.g. Microsoft.EntityFrameworkCore.InMemory, Npgsql.EntityFrameworkCore.PostgreSQL)
Operating system: Windows 10 Professional 15063.540
IDE: Visual Studio Professional 2017 15.3.2

@ajcvickers ajcvickers self-assigned this Aug 30, 2017
@ajcvickers ajcvickers added this to the 2.1.0 milestone Aug 30, 2017
@sierratu
Copy link

sierratu commented Nov 1, 2017

I've also just hit this but from a different angle - using the HasField() fluent method - having upgraded today from dotnetcore1.1 to 2.0 on our project in question. It looks like commit ea1a270 removed the scanning of types in the hierarchy and returns the fields only on the class/entity type being examined - probably not what was intended in the fixing of #7536 even though it does indeed fix it :)

@ajcvickers ajcvickers modified the milestones: 2.1.0-preview1, 2.1.0 Jan 17, 2018
ajcvickers added a commit that referenced this issue Mar 8, 2018
@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Mar 8, 2018
ajcvickers added a commit that referenced this issue Mar 9, 2018
@ajcvickers ajcvickers modified the milestones: 2.1.0-preview2, 2.1.0 Nov 11, 2019
@ajcvickers ajcvickers removed their assignment Sep 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug
Projects
None yet
Development

No branches or pull requests

3 participants