Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No suitable constructor found for entity type string

Yesterday I came her with a similar question about my own made entity type that head some errors. I fixed up these errors but now it throws one on entity type string and I have absolutely no clue how to fix this.

Full exception:

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

This gets thrown when I launch my application: I've written a data seeder to get some data in my database. I've scoped this class in my ConfigureServices and used it in the Configure method.

public void ConfigureServices(IServiceCollection services) {
        services.Configure<CookiePolicyOptions>(options => {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddDbContext<ApplicationDbContext>(options =>
           options.UseSqlServer(
               Configuration.GetConnectionString("DefaultConnection")));
        services.AddScoped<IRatingRepository, RatingRepository>();
        services.AddScoped<IReservationRepository, ReservationRepository>();
        services.AddScoped<DataSeeder>();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env,DataSeeder seeder) {
        if (env.IsDevelopment()) {
            app.UseDeveloperExceptionPage();
            app.UseDatabaseErrorPage();
        } else {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseStatusCodePages();
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseDefaultFiles();
        app.UseCookiePolicy();

        app.UseMvc(routes => {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}"
                );
        });

        seeder.SeedData();
    }

And in this class gets the error thrown:

public class DataSeeder {
    #region Fields
    private readonly ApplicationDbContext _context;
    private Random random;
    private ISet<string> _set;
    #endregion

    #region Constructor
    public DataSeeder(ApplicationDbContext context) {
        _context = context;
        random = new Random();
        _set = new HashSet<string>();
    }
    #endregion

    #region Methods
    public void SeedData() {
        _context.Database.EnsureDeleted();
        if (_context.Database.EnsureCreated()) { //**on this line**

            AddCodes();

            //reservations
            Reservation r1 = new Reservation(new DateTime(2019, 2, 21), "Robbe van de Vyver", "Kip met rijst en currysaus", true, "");
            _context.Reservations.Add(r1);

            _context.SaveChanges();
        }
    }

    private void AddCodes() {
        if (_context.Codes.Count() <= 5) {
            char[] characters = "azertyuiopqsdfghjklmwxcvbn,;:=?+-./+~ù%^$*&éè!çà|@#0123456789AZERTYUIOPQSDFGHJKLMWXCVBN".ToArray();
            for (int i = 0; i < 25; i++) {
                string code = "";
                for (int j = 0; j < 4; i++) {
                    code += characters[random.Next(0, characters.Length)];
                }
                _set.Add(code);
            }
            _context.Codes.AddRange(_set);
            _context.SaveChanges();
        }
    } 
    #endregion

but this isn't the only time this exeception gets thrown, it also gets thrown when I try to load a certain page of my application:

public class ChezMoutController : Controller {

    private IRatingRepository _ratingRepository;
    private IReservationRepository _reservationRepository;

    public ChezMoutController(IRatingRepository ratingRepository, IReservationRepository reservationRepository) {
        _ratingRepository = ratingRepository;
        _reservationRepository = reservationRepository;
    }
    public IActionResult Index() {
        ViewData["foodAverage"] = _ratingRepository.GetAll().Select(r => r.FoodRating).Average();
        ViewData["atmosphereAverage"] = _ratingRepository.GetAll().Select(r => r.AtmosphereRating).Average();
        ViewData["reservations"] = _reservationRepository.GetAll();
        ViewData["DatesLeft"] = new List<DateTime>() { };
        return View(_ratingRepository.GetAll());
    }
}

Every time I try to load the view connected to this Index in this controller, the same exepcetion gets thrown right here:

public class RatingRepository : IRatingRepository {
    private readonly ApplicationDbContext _context;

    public RatingRepository(ApplicationDbContext context) {
        _context = context;
    }

    public void Add(Rating rating) {
        var any = _context.Ratings.Any(r => r.RatingId == rating.RatingId);
        if (!any) {
            _context.Add(rating);
        }

    }

    public IEnumerable<Rating> GetAll() {
        return _context.Ratings.ToList(); //**on this line**
    }

    public void Remove(Rating rating) {
        var any = _context.Ratings.Any(r => r.RatingId == rating.RatingId);
        if (any) {
            _context.Remove(rating);
        }

    }

    public void SaveChanges() {
        _context.SaveChanges();
    }
}

(the interface this class implements:)

    public interface IRatingRepository {
    IEnumerable<Rating> GetAll();
    void Add(Rating rating);
    void Remove(Rating rating);
    void SaveChanges();
}

I think it has something to do with my rating class:

public class Rating {
    #region Fields
    private double _foodRating;
    private double _atmosphereRating;
    #endregion

    #region Properties
    public int RatingId { get; set; }
    public double FoodRating {
        get {
            return _foodRating;
        }
        private set {
            if (value < 0.0 || value > 5.0) {
                throw new ArgumentException("Give a score between 0 and 5 please.");
            }
            _foodRating = value;
        }
    }
    public double AtmosphereRating {
        get {
            return _atmosphereRating;
        }
        private set {
            if (value < 0.0 || value > 5.0) {
                throw new ArgumentException("Give a score between 0 and 5 please.");
            }
            _atmosphereRating = value;
        }
    }
    public string PersonalMessage { get; set; } //not mandatory
    public string Suggestions { get; set; } //not mandatory 
    #endregion

    #region Constructors
    public Rating() {

    }

    public Rating(double foodRating, double atmosphereRating, string personalMessage = null, string suggestions = null):this() {
        FoodRating = foodRating;
        AtmosphereRating = atmosphereRating;
        PersonalMessage = personalMessage;
        Suggestions = suggestions;
    }
    #endregion

}

but I woudln't know what to do to fix this. Any help would be appreciated!

ApplicationDbContext:

 public class ApplicationDbContext : DbContext {
    public DbSet<Rating> Ratings { get; set; }
    public DbSet<Reservation> Reservations { get; set; }
    public DbSet<string> Codes { get; set; }

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder modelBuilder) {
        modelBuilder.ApplyConfiguration(new RatingConfiguration());
        modelBuilder.ApplyConfiguration(new ReservationConfiguration());
    }
}

RatingConfiguartion

public class RatingConfiguration : IEntityTypeConfiguration<Rating> {
    public void Configure(EntityTypeBuilder<Rating> builder) {
        builder.ToTable("Rating");

        builder.HasKey(r => r.RatingId);

        builder.Property(r => r.PersonalMessage)
            .HasMaxLength(250)
            .IsRequired(false);

        builder.Property(r => r.Suggestions)
            .HasMaxLength(250)
            .IsRequired(false);
    }
}
like image 790
Mout Pessemier Avatar asked Jan 28 '19 10:01

Mout Pessemier


3 Answers

The problem is in your context, you have this line:

public DbSet<string> Codes { get; set; }

You need to use a concrete class for your entities, a string cannot be used.

like image 97
DavidG Avatar answered Oct 23 '22 23:10

DavidG


Just had a similar problem.

I had a class and was doing some changes and deleted the default class constructor. All though it is never called EF still needs it or you will get a No suitable constructor found exception

public class Company
{
    public  Company ( )
    {
      // ef needs this constructor even though it is never called by 
     // my code in the application. EF needs it to set up the contexts

      // Failure to have it will result in a 
      //  No suitable constructor found for entity type 'Company'. exception
    }

    public Company ( string _companyName , ......)
    {
         // some code
    }
}
like image 37
BrownPony Avatar answered Oct 24 '22 00:10

BrownPony


This is the same issue I got while adding a new property in my entity and updated the existing constructor and passed new property as a parameter

Fix: Instead of updating an existing constructor, added an overloaded constructor with a new property and this error was gone while creating migration

like image 2
Raza Ashfaq Mirza Avatar answered Oct 23 '22 23:10

Raza Ashfaq Mirza