【问题标题】:System.InvalidOperationException: 'No suitable constructor found for entity type 'HealthCheck'System.InvalidOperationException:'没有找到适合实体类型'HealthCheck'的构造函数
【发布时间】:2019-04-24 20:37:09
【问题描述】:

尝试通过 EF Core 在我的数据库中添加内容时出现此错误。

System.InvalidOperationException: '没有找到合适的构造函数 实体类型“健康检查”。以下构造函数有参数 无法绑定到实体类型的属性:无法绑定 'HealthCheck(string title, string hctype, string link)'中的'hctype'。

这是我的 HealthCheck 课程:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Application.Models
{
    public class HealthCheck
    {
        public HealthCheck(string title, string hctype, string link)
        {
            Title = title;
            HCType = hctype;
            Link = link;
        }

        public int Id { get; set; }
        public string Title { get; set; }
        public string HCType { get; set; }
        public string Link { get; set; }
    }
}

我的存储库上下文

using Microsoft.EntityFrameworkCore;
using Application.Models;

namespace Application.Repository
{
    public class RepositoryContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(
                @"Server=(localdb)\mssqllocaldb;Database=healthcheck;Integrated Security=True");
        }

        //public DbSet<HealthCheck> HealthChecks { get; set; }
        //public DbSet<UserHealthCheck> UserHealthChecks { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<HealthCheck>().ToTable("HealthCheck");
            modelBuilder.Entity<UserHealthCheck>().ToTable("UserHealthCheck");
        }
    }
}

我的仓库

using Application.Models;

namespace Application.Repository
{
    public class Repository
    {
        public void InsertHealthCheck(HealthCheck healthCheck)
        {
            using (var db = new RepositoryContext())
            {
                db.Add(healthCheck);
                db.SaveChanges();
            }
        }
    }
}

这就是“InsertHealthCheck()”被调用的地方

[Route("/api/HealthCheck/Website")]
        [HttpPost]
        public ActionResult WebsiteStatus([FromBody] WebsiteDataModel websiteData)
        {
            HealthCheck data = new HealthCheck(websiteData.Title, "Website", websiteData.Url);
            try
            {
                HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(websiteData.Url);
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                HttpStatusCode HealthCheckStatusCode = myHttpWebResponse.StatusCode;
                myHttpWebResponse.Close();
                return Ok(HealthCheckStatusCode);
            }
            catch(UriFormatException)
            {
                return Ok("Check url.");
            }
            catch (Exception)
            {
                return Ok("400");
            }
            finally
            {
                repository.InsertHealthCheck(data);
            }
        }

如果您能帮帮我,我将不胜感激,如果您需要我发布代码的任何其他部分,请询问。

另外,我刚开始学习 EF Core,所以如果我做了一些非常愚蠢的事情,请指出

【问题讨论】:

    标签: c# asp.net model-view-controller entity-framework-core


    【解决方案1】:

    提供无参数构造函数可以避免该问题,但这不是 OP 案例中错误的真正原因。 EF Core 2.1 and higher uses a strict convention to map constructor parameters to property names of the entity. 它期望构造函数参数的名称是帕斯卡大小写的属性名称的真正驼峰式表示。如果您将参数名称从“hctype”更改为“hCType”,您应该不会收到错误,并且如果您的领域驱动设计方法表明它会出现问题,必须提供无参数构造函数这样做。

    但是,如果您只是为了方便而提供参数化构造函数,但调用者能够使用“new”运算符实例化 HealthCheck 并没有什么不妥,那么简单地添加无参数构造函数是可以接受的。

    【讨论】:

      【解决方案2】:

      你缺少空的构造函数:

      public class HealthCheck
      {
         // here
         public HealthCheck()
         {
         }
      
         public HealthCheck(string title, string hctype, string link)
         {
             Title = title;
             HCType = hctype;
             Link = link;
         }
      
         public int Id { get; set; }
         public string Title { get; set; }
         public string HCType { get; set; }
         public string Link { get; set; }
      
      
      }
      

      这样试试

      【讨论】:

      • 谢谢!我确信它必须非常简单。
      【解决方案3】:

      我遇到了这个异常。

      没有为实体类型“博客”找到合适的构造函数。以下构造函数具有无法绑定到实体类型属性的参数:无法在“博客(字符串名称)”中绑定“名称”;无法在“博客(int id,字符串名称)”中绑定“名称”。

      我通过两种方式缓解了这种情况。

      先看看我的博客类。

      public class Blog
      {
          public Blog(string name)
          {
              Name = name;
          }
      
          private Blog(int id, string name)
          {
              Id = id;
              Name = name;
          }
          public int Id { get; private set; }
          public string Name { get; } // Note: No setter, it's a readonly prop. 
          public List<Post> Posts { get; } = new();
      }
      

      请注意,Name 没有设置器。

      所以第一种方法是添加私有 setter。现在它不再是只读道具。可以在类中设置。

      public string Name { get; private set; }
      

      应用程序运行无异常。

      但是,如果您坚持将 Name 属性保留为只读,这是另一种方式。我们需要向上下文添加显式配置,如下所示。在这里,我们告诉 Ef Core 显式映射它。 Ef Core 默认不映射只读属性。

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          base.OnModelCreating(modelBuilder);
          // Ef does not map readonly properties by default, we have to 
          // ask ef to map the Name even though Name is readonly
          modelBuilder.Entity<Blog>(b => b.Property(e => e.Name));
      }
      

      【讨论】:

      • 记录一下:这甚至适用于仅 getter 属性(EF 核心 5)。
      【解决方案4】:

      由于HealthCheck 类在您的数据库中代表一个,因此您必须提供一个空的构造函数。
      尝试以下实现,如果您仍然收到相同的错误,请告诉我:

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Threading.Tasks;
      
      namespace Application.Models
      {
          public class HealthCheck
          {
              public HealthCheck()
              {
              }
      
              public HealthCheck(string title, string hctype, string link)
              {
                  Title = title;
                  HCType = hctype;
                  Link = link;
              }
      
              public int Id { get; set; }
              public string Title { get; set; }
              public string HCType { get; set; }
              public string Link { get; set; }
          }
      }
      

      【讨论】:

      • 如果你检查我的答案,我在你之前写过,所以你的答案和我的完全一样
      【解决方案5】:

      出现此错误的方法有很多 :-( 这是另一种方法:

      只读属性不按约定映射 [... 即使 PropertyName / constructorParameterNames 准确地遵循 PascalCase/camelCase 匹配约定...],因此没有匹配构造函数的映射属性。像这样映射属性应该会导致构造函数被正确使用:

      modelBuilder.Entity<A>(b =>
      {
          b.Property(e => e.Id).ValueGeneratedNever();
          b.Property(e => e.Name);                
      });
      

      https://github.com/dotnet/efcore/issues/14336

      但这里是 2021 年 ef core 规则的摘要,应该涵盖大多数罐头和罐头:

      https://docs.microsoft.com/en-us/ef/core/modeling/constructors

      【讨论】:

        猜你喜欢
        • 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
        相关资源
        最近更新 更多