【问题标题】:No suitable constructor found for entity type string没有为实体类型字符串找到合适的构造函数
【发布时间】:2022-04-15 21:57:46
【问题描述】:

昨天我向她提出了一个关于我自己制作的实体类型的类似问题,该类型导致了一些错误。我修复了这些错误,但现在它在实体类型字符串上抛出一个错误,我完全不知道如何解决这个问题。

完全例外:

System.InvalidOperationException: '没有为实体类型'字符串'找到合适的构造函数。以下参数无法绑定到实体的属性:'value'、'value'、'startIndex'、'length'、'value'、'value'、'startIndex'、'length'、'value'、' value'、'startIndex'、'length'、'value'、'startIndex'、'length'、'enc'、'c'、'count'、'value'。

当我启动我的应用程序时会抛出这个问题:我编写了一个数据播种器来在我的数据库中获取一些数据。我在ConfigureServices 中定义了这个类,并在Configure 方法中使用了它。

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();
    }

并且在这个类中得到了抛出的错误:

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

但这不是唯一一次引发此异常,当我尝试加载应用程序的某个页面时也会引发此异常:

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());
    }
}

每次我尝试在此控制器中加载连接到此索引的视图时,都会在此处抛出相同的异常:

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();
    }
}

(这个类实现的接口:)

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

我认为这与我的评分等级有关:

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

}

但我不知道该怎么做才能解决这个问题。 任何帮助将不胜感激!

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());
    }
}

评级配置

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);
    }
}

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案1】:

    问题出在你的上下文中,你有这行:

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

    您需要为实体使用具体类,不能使用string

    【讨论】:

    • 那你建议我做什么?制作一个具有字符串属性的类代码?
    • 这里的人不可能告诉你,这是你的桌子,你需要定义类。
    • 好的,我会找到解决办法的,非常感谢!我会尽快接受答案!
    【解决方案2】:

    刚刚遇到类似的问题。

    我有一个类并且正在做一些更改并删除了默认的类构造函数。尽管它从未被调用过,但 EF 仍然需要它,否则你会得到一个找不到合适的构造函数异常

    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
        }
    }
    

    【讨论】:

    • 从 EF Core 2.1 开始不再是这种情况;您不需要 EF Core 的空构造函数。 EF Core documentation 声明 当 EF Core 创建实例 [...] 时,它将首先调用默认的无参数构造函数 [...]。但是,如果 EF Core 找到参数化构造函数 [...],那么它将改为使用这些属性的值调用参数化构造函数
    • 至少将默认构造函数设为私有然后
    【解决方案3】:

    这与我在实体中添加新属性并更新现有构造函数并将新属性作为参数传递时遇到的相同问题

    修复: 没有更新现有的构造函数,而是添加了具有新属性的重载构造函数,并且在创建迁移时此错误消失了

    【讨论】:

      【解决方案4】:

      这已部分回答,但在 EF Core 中有一个关于此问题的一般准则。

      当您在实体类中定义实体时,您需要确保整个事物是公开的和可访问的。例如,

      public class GroupMap
          {
              [Key] public int Id { get; set; }
              public string GroupId { get; set; }
          }
      

      有两个属性,Id(有一个冗余的 [Key] 注释)和 GroupId。想想 GroupId,它必须是一个公共属性,并且必须同时定义它的 getter 和 setter。

      所以这会失败:

      public class GroupMap
          {
              [Key] public int Id { get; set; }
              private string GroupId { get; set; }  // private property not allowed
          }
      

      这样:

      public class GroupMap
          {
              [Key] public int Id { get; set; }
              public string GroupId { get; } // setter must be defined
          }
      

      由于 EF Core 是 ORM,您还需要确保属性类型对数据库有意义(尽管我无法在此提供太多细节)。最后,如其他地方所述,您还需要提供正确的上下文定义。所有相同的规则都适用。

      例如:

      public DbSet<Item> Items { get; set; } // public, and getter & setter defined
      

      正如其他地方所述,DbSet 类型需要是一个具体的类,它定义了您希望成为表中的列或与另一个表的关系的各种属性。

      希望能帮助到那里的人。

      【讨论】:

        【解决方案5】:

        就我而言,在我为正在映射的字段/属性更正大小写后,此错误得到解决。

        我建议使用:

        -字段的骆驼案例

        -属性的帕斯卡大小写。即使您的属性名称类似于“DBProperty”,也将其更改为“DbProperty”

        【讨论】:

          【解决方案6】:

          @DavidG 和 @BrownPony 是正确的,但我想补充一些信息:

          不能像public Company (string companyName = "") 这样在构造函数中添加默认值,但您可以使用私有构造函数。

          https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/named-and-optional-arguments#example-1

          public class Company
          {
              private Company ( )
              {
              }
          
              public Company (string companyName)
              {
                   // some code
              }
          }
          

          https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/private-constructors

          https://stackoverflow.com/a/31543487/3850405

          【讨论】:

            【解决方案7】:

            在向实体模型添加新属性,然后在构造函数中设置该属性时,我遇到了同样的问题。验证构造函数的大小写模式是否与属性匹配。

            【讨论】:

            • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
            • 这并不能真正回答问题。如果您有其他问题,可以点击 进行提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
            猜你喜欢
            • 2019-03-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-20
            • 2021-08-15
            相关资源
            最近更新 更多