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

No suitable constructor found for entity type 'string' #11074

Closed
bradmarder opened this issue Feb 27, 2018 · 19 comments
Closed

No suitable constructor found for entity type 'string' #11074

bradmarder opened this issue Feb 27, 2018 · 19 comments
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

@bradmarder
Copy link

Unhandled Exception: System.InvalidOperationException: No suitable constructor found for entity type 'string'. The following parameters could not be bound to properties of the entity: 'value', 'startIndex', 'length', 'enc', 'value', 'startIndex', 'length', 'value', 'startIndex', 'length', 'value', 'startIndex', 'length', 'c', 'count', 'value', 'value', 'value', 'value'.
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConstructorBindingConvention.Apply(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
   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.Internal.InternalAccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.get_DatabaseCreator()
   at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureCreatedAsync(CancellationToken cancellationToken)

Testing out <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0-preview1-final" /> and EFCore just throws this. I'm completely lost in how to approach this.

Further technical details

EF Core version: Microsoft.AspNetCore.App 2.1.0-preview1-final
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: win10 x64
IDE: Visual Studio 2017 Preview 2 15.6.0 Preview 6.0

@ajcvickers
Copy link
Member

@bradmarder Can you provide more details on how you are using this package? For example, which feed are you using? Which .NET Core installer did you run? What are you using to build?

@bradmarder
Copy link
Author

bradmarder commented Feb 27, 2018

@ajcvickers

  1. Feeds used inside nuget.config
  1. Using Microsoft .NET Core SDK Preview 2.1.300.8261 from https://github.com/dotnet/cli
  2. dotnet run -c release

As for other details, theres a lot. Everything worked with aspnetcore.all 2.05 package, and I changed my target frameworks to netcoreapp2.1. I'm using openiddict. Also, I did not convert any of my models to use the lazyloading services yet. I don't reference Microsoft.EntityFrameworkCore.Proxies. Many models have multiple constructors, and all include a private parameterless constructor.

@smitpatel
Copy link
Contributor

@bradmarder - Can you share your model details? Do you have entityType named string or is it primitive type string getting expanded as an EntityType.

@Alexxtheonly
Copy link

Alexxtheonly commented Feb 28, 2018

Got the same issue.

Model:

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

    public CollectionComplexType<int> DeviceIds { get; set; }

    public CollectionComplexType<int> TimespanIds { get; set; }

    public int AccessDaysId { get; set; }
  }

ComplexType:

  public class CollectionComplexType<T> : Collection<T>
  {
    public CollectionComplexType()
    {
    }

    public string Serialized
    {
      get => JsonConvert.SerializeObject(this);
      private set
      {
        Clear();

        if (string.IsNullOrEmpty(value))
        {
          return;
        }

        foreach (var item in JsonConvert.DeserializeObject<T[]>(value))
        {
          Add(item);
        }
      }
    }
  }

DbContext:

      modelBuilder.Entity<TransferAccessProfile>(e =>
      {
        e.HasKey(o => o.Id);
        e.OwnsOne(o => o.DeviceIds).Property(o => o.Serialized).HasColumnName(nameof(TransferAccessProfile.DeviceIds));
        e.OwnsOne(o => o.TimespanIds).Property(o => o.Serialized).HasColumnName(nameof(TransferAccessProfile.TimespanIds));
      });

Exception:
No suitable constructor found for entity type 'string'. The following parameters could not be bound to properties of the entity: 'value', 'startIndex', 'length', 'enc', 'value', 'startIndex', 'length', 'value', 'startIndex', 'length', 'value', 'startIndex', 'length', 'c', 'count', 'value', 'value', 'value', 'value'.

Worked with 2.0

@bradmarder
Copy link
Author

bradmarder commented Feb 28, 2018

@smitpatel @ajcvickers

Narrowed it down a lot. I removed all db entities. Only left with registering identity stuff.

    public class FooContext : IdentityDbContext<FooUser, Microsoft.AspNetCore.Identity.IdentityRole<Guid>, Guid>
    {
        public FooContext(DbContextOptions options) : base(options) { }
    }

public class FooUser : IdentityUser<Guid>, IFooUser { }

.AddDbContextPool<FooContext>

@smitpatel
Copy link
Contributor

@bradmarder - I am not able to get it to work with modifications you provided. I took MVC web app template and modified ApplicationDbContext as your code and I m hitting error.

Error: GenericArguments[0], 'Microsoft.AspNetCore.Identity.IdentityUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type 'TUser'.

It would be useful if you can provide us a sample solution demonstrating the issue or find minimum repro without use of Identity.

@smitpatel
Copy link
Contributor

@Alexxtheonly - The model you shared is working fine in 2.1.0-preview1-final
Following works fine for me. (Commented out Json serialization since I am not referencing that package in my project)

using System;
using System.Collections.ObjectModel;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;

namespace EFSampleApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using (var db = new MyContext())
            {
                // Recreate database
                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                // Seed database


                db.SaveChanges();
            }

            using (var db = new MyContext())
            {
                // Run queries

            }

            Console.WriteLine("Program finished.");
        }
    }


    public class MyContext : DbContext
    {
        private static ILoggerFactory LoggerFactory => new LoggerFactory().AddConsole(LogLevel.Trace);

        // Declare DBSets
        public DbSet<TransferAccessProfile> Blogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // Select 1 provider
            optionsBuilder
                .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
                //.UseSqlite("filename=_modelApp.db")
                //.UseInMemoryDatabase(databaseName: "_modelApp")
                .EnableSensitiveDataLogging()
                .UseLoggerFactory(LoggerFactory);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Configure model
            modelBuilder.Entity<TransferAccessProfile>(e =>
            {
                e.HasKey(o => o.Id);
                e.OwnsOne(o => o.DeviceIds).Property(o => o.Serialized).HasColumnName(nameof(TransferAccessProfile.DeviceIds));
                e.OwnsOne(o => o.TimespanIds).Property(o => o.Serialized).HasColumnName(nameof(TransferAccessProfile.TimespanIds));
            });
        }
    }

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

        public CollectionComplexType<int> DeviceIds { get; set; }

        public CollectionComplexType<int> TimespanIds { get; set; }

        public int AccessDaysId { get; set; }
    }

    public class CollectionComplexType<T> : Collection<T>
    {
        public CollectionComplexType()
        {
        }

        public string Serialized
        {
            get => "";// JsonConvert.SerializeObject(this);
            private set
            {
                Clear();

                if (string.IsNullOrEmpty(value))
                {
                    return;
                }

                //foreach (var item in JsonConvert.DeserializeObject<T[]>(value))
                //{
                //    Add(item);
                //}
            }
        }
    }
}

@Alexxtheonly
Copy link

Alexxtheonly commented Mar 1, 2018

@smitpatel
I created a sample project. https://github.com/Alexxtheonly/NoSuitableConstructor-11074
The error seems to be related to using a dictionary as complex type. At least in my case.

@smitpatel
Copy link
Contributor

Thanks for repro code @Alexxtheonly
Simplified repro:

using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Logging;

namespace EFSampleApp
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using (var db = new MyContext())
            {
                // Recreate database
                db.Database.EnsureDeleted();
                db.Database.EnsureCreated();

                // Seed database
                var test = new DictionaryComplexType<int, string>();
                db.Add(new TestModel()
                {
                    Id = 1,
                    Ints = test,
                });

                db.SaveChanges();
            }

            using (var db = new MyContext())
            {
                // Run queries

            }

            Console.WriteLine("Program finished.");
        }
    }


    public class MyContext : DbContext
    {
        private static ILoggerFactory LoggerFactory => new LoggerFactory().AddConsole(LogLevel.Trace);

        // Declare DBSets
        public DbSet<TestModel> TestModels { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            // Select 1 provider
            optionsBuilder
                .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
                //.UseSqlite("filename=_modelApp.db")
                //.UseInMemoryDatabase(databaseName: "_modelApp")
                .EnableSensitiveDataLogging()
                .UseLoggerFactory(LoggerFactory);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // Configure model
            modelBuilder.Entity<TestModel>(e =>
            {
                e.HasKey(o => o.Id);
                e.OwnsOne(o => o.Ints);
            });

            Console.WriteLine((modelBuilder.Model as Model)?.ToDebugString());
        }
    }

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

    public class TestModel
    {
        public int Id { get; set; }
        public DictionaryComplexType<int, string> Ints { get; set; }
    }

    public class DictionaryComplexType<TKey, TValue> : Dictionary<TKey, TValue>
    {
    }
}

We started discovering properties in Dictionary and expanded Dictionary.Values as collection navigation which is ICollection in this case.

@smitpatel
Copy link
Contributor

Assigning to @AndriySvyryd

@smitpatel smitpatel removed this from the 2.1.0 milestone Mar 1, 2018
@ajcvickers ajcvickers added this to the 2.1.0 milestone Mar 2, 2018
@JohnFlyIII
Copy link

Got hit with this also.
Going to see where the problem lies in my setup, but any update from the team would be great.

@bradmarder
Copy link
Author

bradmarder commented Mar 9, 2018

@ajcvickers I just found a very simple repo.

Just add public IEnumerable<string> Types => null; to any model

Adding the attribute [System.ComponentModel.DataAnnotations.Schema.NotMapped] solves the issue.

@JohnFlyIII
Copy link

Just had another run in with this issue.
Turned out to be use of System.Uri

Curious if it was some sort of default value or constructor issue I set a default value in my modelbuilder..
Which then let me to "type 'Uri' which is not supported by current database provider. " being thrown.

I switched my System.Uri to string and things are back to operational.

AndriySvyryd added a commit that referenced this issue Mar 14, 2018
Handle OwnedAttribute correctly
Convert types to owned in a more robust way

Fixes #11074
Fixes #11152
AndriySvyryd added a commit that referenced this issue Mar 14, 2018
Handle OwnedAttribute correctly
Convert types to owned in a more robust way

Fixes #11074
Fixes #11152
@AndriySvyryd AndriySvyryd removed their assignment Mar 14, 2018
@AndriySvyryd AndriySvyryd added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Mar 14, 2018
@jholovacs
Copy link

When does this change become a nuget package? It zinged me yesterday.

@ajcvickers
Copy link
Member

@jholovacs It will be in the nightly builds (listed on the homepage) first--probably already, although I didn't check, and it will get to nuget.org as part of the preview2 release.

@joacar
Copy link

joacar commented Jun 1, 2018

This issue will also arise in inheritance if the inherited doesn't provide a default constructor. Example

public class Enumeration<TValue>
{
    public TValue Value { get; private set; }
    
   public string Display {get; private set; }

  public Enumeration(TValue value, string display) { ... }

  protected Enumeration() { /* ORM */ }
}

public class Type : Enumeration<int>
{
  public class Type(int id, string display) : base(id, display) { .. }
  
  // This fixes the issue in 2.1.0
  protected Type() { /* ORM */ }
}

2.1 prior fix

System.InvalidOperationException: No suitable constructor found for entity type 'PlatformType'. The following parameters could not be bound to properties of the entity: 'id', 'display'.

Stack trace

WebApp>    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConstructorBindingConvention.Apply(InternalModelBuilder modelBuilder)
WebApp>    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder)
WebApp>    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder)
WebApp>    at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.Validate()
WebApp>    at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
WebApp>    at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__1()
WebApp>    at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
WebApp>    at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
WebApp>    at System.Lazy`1.CreateValue()
WebApp>    at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
WebApp>    at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
WebApp>    at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
WebApp>    at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_1(IServiceProvider p)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProviderEngineScope scope)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
WebApp>    at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
WebApp>    at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
WebApp>    at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
WebApp>    at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
WebApp>    at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
WebApp>    at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.GetRelationalService[TService](IInfrastructure`1 databaseFacade)
WebApp>    at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.GetMigrations(DatabaseFacade databaseFacade)
WebApp>    at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.GetPendingMigrations(DatabaseFacade databaseFacade)

@ajcvickers
Copy link
Member

@jholovacs The exception you posted indicates that no matching properties could be found for "id" and "display". This is a completely different error than the one posted for this bug. Also, the code you posted is incomplete and has errors, but when I correct things and attempt to repro I get a different message--it finds the Display property, as expected, but can't match "id" because there is no "Id" property. This is all as expected. If after reconsidering this you believe there is still a bug, then please file a new issue including a runnable project/solution or code listing that reproduces the behavior.

@jholovacs
Copy link

...huh? I don't believe I posted an exception?

@ajcvickers
Copy link
Member

@jholovacs Sorry! I meant to mention @joacar

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

8 participants