No suitable constructor found for entity type MyImage

12,825

EF.Core calls entity constructors internally, so EF.Core should somehow determine what to pass as parameter. EF.Core < 2.1 wasn't able to inject parameters at all, but starting from EF.Core 2.1 it is possible - if all parameters have same names as properties, EF.Core uses properties values as parameters values (see docs for more info):

Starting with EF Core 2.1, it is now possible to define a constructor with parameters and have EF Core call this constructor when creating an instance of the entity. The constructor parameters can be bound to mapped properties, or to various kinds of services to facilitate behaviors like lazy-loading.

In your case it's not possible to parse Image image parameter (EF.Core 2.1, older EF.Core won't work at all), so simple solution is to add default constructor to your MyImage class.

Share:
12,825
Mout Pessemier
Author by

Mout Pessemier

Updated on August 31, 2022

Comments

  • Mout Pessemier
    Mout Pessemier over 1 year

    I'm getting this exception:

    System.InvalidOperationException HResult=0x80131509 Message=No suitable constructor found for entity type 'MyImage'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'image' in 'MyImage(string name, string country, Image image)'. Source=Microsoft.EntityFrameworkCore StackTrace: at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConstructorBindingConvention.Apply(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.Validate() at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel() at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.b__1() at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode) at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue() 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_2(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(IServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.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.Internal.InternalAccessorExtensions.GetService[TService](IInfrastructure1 accessor) at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor) at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.get_DatabaseCreator() at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureDeleted() at DigitizedApi.Data.DataInitializer.InitializeData() in D:\School\Webapplicaties IV\DigitizedApi\DigitizedApi\DigitizedApi\Data\DataInitializer.cs:line 27 at DigitizedApi.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, DataInitializer dataInitializer) in D:\School\Webapplicaties IV\DigitizedApi\DigitizedApi\DigitizedApi\Startup.cs:line 103

    and I have no clue what the reason could be.

    DB context

        public class ApplicationDbContext : IdentityDbContext {
    
        public DbSet<MyImage> Images { get; set; }
        public DbSet<Visitor> Visitors { get; set; }
    
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options) {
        }
    
        protected override void OnModelCreating(ModelBuilder builder) {
            base.OnModelCreating(builder);
            builder.ApplyConfiguration(new ImageConfiguration());
            builder.ApplyConfiguration(new VisitorConfiguration());
            builder.ApplyConfiguration(new ImageVisitorConfiguration());
        }
    }
    

    Data initializer

            private readonly ApplicationDbContext _dbContext;
        private readonly UserManager<IdentityUser> _userManager;
        private readonly IImageRepository _imageRepository;
    
        public DataInitializer(ApplicationDbContext context, UserManager<IdentityUser> userManager, IImageRepository imageRepository) {
            _dbContext = context;
            _userManager = userManager;
            _imageRepository = imageRepository;
        }
    
        //public async Task InitializeData() {
        //    _dbContext.Database.EnsureDeleted();
        //    if (_dbContext.Database.EnsureCreated()) {
        //    }
        //}
    
        public void InitializeData() {
            _dbContext.Database.EnsureDeleted();//error gets thrown here
            if (_dbContext.Database.EnsureCreated()) {
                //MyImage image1 = new MyImage("Parallax1","France",Image.FromFile("DSC_2544c2.jpg"));
                //_imageRepository.Add(image1);
    
                _imageRepository.SaveChanges();
    
    
    
            }
        }
    
        private async Task CreateUser(string email, string password) {
            var user = new IdentityUser { UserName = email, Email = email };
            await _userManager.CreateAsync(user, password);
        }
    }
    

    MyImage Class

        public class MyImage {
    
        #region Fields
        private string _name;
        #endregion
    
        #region Properties
        public int Id { get; set; }
        [Required]
        public string Name {
            get {
                return _name;
            }
    
            set {
                if (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value)) {
                    throw new ArgumentException("Name cannot be empty.");
                }
                _name = value;
            }
        }
        public int ISO { get; set; }
        public double ShutterSpeed { get; set; }
        public double Aperture { get; set; }
        public string Country { get; set; }
        public string Content { get; set; }
        #endregion
    
        #region Constructor
        //public MyImage(string name, int iso, double shutterspeed, double aperture, string country, string content) {
        //    Name = name;
        //    ISO = iso;
        //    ShutterSpeed = shutterspeed;
        //    Aperture = aperture;
        //    Country = country;
        //    Content = content;
    
        //}
    
        public MyImage(string name, string country, Image image) {
            Name = name;
            ISO = Convert.ToInt32(Encoding.UTF8.GetString(image.GetPropertyItem(0x8828).Value));
            ShutterSpeed = Convert.ToInt64(Encoding.UTF8.GetString(image.GetPropertyItem(0x9201).Value));
            Aperture = Convert.ToInt32(Encoding.UTF8.GetString(image.GetPropertyItem(0x9202).Value)); ;
            Country = country;
            Content = ConvertImage(image);
    
        }
        #endregion
    
        #region Methods
        private string ConvertImage(Image imageToConvert) {
            byte[] Ret;
            try {
                using (MemoryStream ms = new MemoryStream()) {
                    imageToConvert.Save(ms, imageToConvert.RawFormat);
                    Ret = ms.ToArray();
                }
            } catch (Exception ex) {
                throw;
            }
            return Convert.ToBase64String(Ret);
        }
        #endregion
    }
    

    Configuration

        public class ImageConfiguration : IEntityTypeConfiguration<MyImage> {
        public void Configure(EntityTypeBuilder<MyImage> builder) {
            builder.ToTable("Image");
    
            builder.HasKey(i => i.Id);
    
            builder.Property(i => i.Name)
                .HasMaxLength(40)
                .IsRequired(true);
    
            builder.Property(i => i.Country)
                .HasMaxLength(84)
                .IsRequired(true);
    
            builder.Property(i => i.Content)
                .IsRequired(true);
        }
    }
    

    Visitor class

        public class Visitor {
    
        #region Fields
        private string _name;
        private string _email;
        private string _telephone;
        #endregion
    
        #region Properties
        public int Id { get; set; }
        public string Name {
            get {
                return _name;
            }
            set {
                if (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value)) {
                    throw new ArgumentException("Name can't be empty.");
                }
                _name = value;
            }
        }
    
        public string Email {
            get {
                return _email;
            }
            set {
                if (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value)) {
                    throw new ArgumentException("Email can't be empty.");
                }
                Regex regex = new Regex(@"^([a-zA-Z0-9éèà]+[a-zA-Z0-9.-éèàïëöüäîôûêâù]*)@([a-zA-Z]+)[.]([a-z]+)([.][a-z]+)*$");
                Match match = regex.Match(value);
                if (!match.Success) {
                    throw new ArgumentException("Email doesn't have a correct format.");
                }
                _email = value;
            }
        }
    
        public string Telephone {
            get {
                return _telephone;
            }
            set {
                if (string.IsNullOrEmpty(value) || string.IsNullOrWhiteSpace(value)) {
                    throw new ArgumentException("Telephone number can't be empty.");
                }
                Regex regex = new Regex(@"(\+(0)?|00)(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{1,14}$");
                Match match = regex.Match(value);
                if (!match.Success) {
                    throw new ArgumentException("Telephone number doesn't have a correct format. " +
                        "Please make sure you use an international phone number (+44791112345) and dont forget to add the +.");
                }
                _telephone = value;
            }
        }
    
        public string Country { get; set; }
    
        public ICollection<LikedImage> Liked { get; private set; }
        public IEnumerable<MyImage> LikedImages => Liked.Select(i => i.Image);
        #endregion
    
        #region Constructor
        public Visitor(string name, string email, string telephone, string country = null) {
            Name = name;
            Email = email;
            Telephone = telephone;
            Country = country;
        }
        #endregion
    }
    

    Visitor configuration

    public class VisitorConfiguration : IEntityTypeConfiguration<Visitor> {
        public void Configure(EntityTypeBuilder<Visitor> builder) {
            builder.ToTable("Visitors");
    
            builder.HasKey(v => v.Id);
    
            builder.Property(v => v.Name)
                .HasMaxLength(50)
                .IsRequired(true);
    
            builder.Property(v => v.Email)
                .HasMaxLength(70)
                .IsRequired(true);
    
            builder.Property(v => v.Telephone)
                .HasMaxLength(15)
                .IsRequired(true);
        }
    }
    

    Intersection table

       public class LikedImage {
        #region Properties
        public int ImageId { get; set; }
    
        public int VisitorId { get; set; }
    
        public Visitor Visitor { get; set; }
    
        public MyImage Image { get; set; }
        #endregion
    }
    

    it's configuration

        public class ImageVisitorConfiguration : IEntityTypeConfiguration<LikedImage> {
        public void Configure(EntityTypeBuilder<LikedImage> builder) {
            builder.HasKey(i => new { i.ImageId, i.VisitorId });
    
            builder.HasOne(i => i.Visitor)
                .WithMany(v => v.Liked)
                .HasForeignKey(i => i.VisitorId);
    
            builder.HasOne(i => i.Image)
                .WithMany()
                .HasForeignKey(i => i.ImageId);
        }
    }
    

    and finally

    startup

        public class Startup {
        public Startup(IConfiguration configuration) {
            Configuration = configuration;
        }
    
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services) {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
            services.AddDbContext<ApplicationDbContext>(options =>
              options.UseSqlServer(Configuration.GetConnectionString("DigitizedContext")));
    
            services.AddScoped<DataInitializer>();
            services.AddScoped<IImageRepository, ImageRepository>();
            services.AddScoped<IVisitorRepository, VisitorRepository>();
    
            services.AddOpenApiDocument(c => {
                c.DocumentName = "apidocs";
                c.Title = "DigitizedAPI";
                c.Version = "v1";
                c.Description = "The DigitizedAPI documentation description.";
                c.DocumentProcessors.Add(new SecurityDefinitionAppender("JWT Token", new SwaggerSecurityScheme {
                    Type = SwaggerSecuritySchemeType.ApiKey,
                    Name = "Authorization",
                    In = SwaggerSecurityApiKeyLocation.Header,
                    Description = "Copy 'Bearer' + valid JWT token into field"
                }));
                c.OperationProcessors.Add(new OperationSecurityScopeProcessor("JWT Token"));
            });
    
            services.AddIdentity<IdentityUser, IdentityRole>(cfg => cfg.User.RequireUniqueEmail = true).AddEntityFrameworkStores<ApplicationDbContext>();
            services.Configure<IdentityOptions>(options => {
    
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 3;
                options.Lockout.AllowedForNewUsers = true;
    
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-._@+";
                options.User.RequireUniqueEmail = true;
            });
    
            services.AddAuthentication(x => {
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            }).AddJwtBearer(x => {
                x.RequireHttpsMetadata = false;
                x.SaveToken = true;
                x.TokenValidationParameters = new TokenValidationParameters {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Tokens:Key"])),
                    ValidateIssuer = false,
                    ValidateAudience = false,
                    RequireExpirationTime = true
                };
            });
    
            //change later to the origen of my site
            services.AddCors(options =>
        options.AddPolicy("AllowAllOrigins", builder => builder.AllowAnyOrigin()
    ));
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, DataInitializer dataInitializer) {
            if (env.IsDevelopment()) {
                app.UseDeveloperExceptionPage();
            } else {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }
    
            app.UseHttpsRedirection();
    
            app.UseAuthentication();
    
            app.UseMvc();
    
            app.UseSwaggerUi3();
            app.UseSwagger();
    
            app.UseCors("AllowAllOrigins");
    
            //dataInitializer.InitializeData().Wait();
            dataInitializer.InitializeData();
        }
    }
    

    I'm very sorry, I know it's a lot of code but I'm a student and my teacher has kind of forsaken us and we need to find things out on our own and I wouldn't know what could be wrong.

    Thanks in advance!

    • ingvar
      ingvar about 5 years
      try to add public MyImage() {}
    • Mout Pessemier
      Mout Pessemier about 5 years
      @ingvar thanks! Could you also explain why it needs this default constructor? I'd like to learn from my mistakes :)
    • ingvar
      ingvar about 5 years
      I will post an answer with explanation