为啥我必须为 Code First / Entity Framework 提供无参数构造函数

Posted

技术标签:

【中文标题】为啥我必须为 Code First / Entity Framework 提供无参数构造函数【英文标题】:Why must I have a parameterless constructor for Code First / Entity Framework为什么我必须为 Code First / Entity Framework 提供无参数构造函数 【发布时间】:2015-10-11 03:43:28 【问题描述】:

这更像是一个“我们为什么做事”的问题,因为我的实际问题已经解决了,但我不知道为什么。

我在 CountyRepository 中处理以下代码:

public IEnumerable<County> GetCounties(string stateAbbr)
    
        using (var db = new AppDbContext())
        
            State state = (from s in db.States
                         where s.Abbr == stateAbbr
                         select s).First();

            return context.Counties.Where(c => c.StateID == state.StateID).ToList();
        
    

我在上面创建的 AppDbContext 将转到自定义初始化器:

  public class AppDbContextInitializer : DropCreateDatabaseIfModelChanges<AppDbContext> 

    protected override void Seed(AppDbContext context)
    
        StatesList states = new StatesList();
        context.States.AddRange(states);
        context.Counties.AddRange(new CountiesList(states));

        context.SaveChanges();
    

问题是,当我执行代码时,AppDbContext 会在 Initializer 中正确加载州和县信息,但是当它返回到县存储库时,AppDbContext 是空的,并且由于“州没有无参数”而出错构造函数”。我不希望我的 State 对象有一个无参数的构造函数,所以我整天都在寻找解决方案,以解决为什么 AppDbContext 会加载到 County Repository 中。我终于找到了以下解决方案:

Exception when loading related objects. Entity Framework

这是一个简单的解决方案。添加无参数构造函数并将其标记为已过时。我这样做了,而且效果很好。

我的问题是,为什么我必须这样做?我使用自定义 Initializer 浏览了 CodeFirst 的多个示例,但没有一个提到需要空构造函数或将其标记为已过时。

是否有更好的解决方案或至少有一个解释,以便我可以用知识而不是困惑继续前进?

【问题讨论】:

如果您的状态类有自定义构造函数,那么您还必须提供另一个构造函数(不带参数)。为什么? .net 的规则。 @BKSpureon 好吧,这并不完全正确。如果您没有定义构造函数,则存在隐式默认构造函数(无参数)。如果你指定了一个构造函数,并且想同时使用参数化和无参数,那么你必须明确地指定它。 【参考方案1】:

必须有一个无参数的构造函数,但它可以是内部的或私有的。 ref question 3

【讨论】:

我将无参数构造函数更改为私有后开始出现异常。看起来在更改之后,该特定模型中的所有复杂类型都返回 null。 这个构造函数是通过实体框架的反射调用的

以上是关于为啥我必须为 Code First / Entity Framework 提供无参数构造函数的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework应用:使用Code First模式管理数据库创建和填充种子数据

为啥 Code First 的 Add-migration 命令包含所有数据库,而不是我对实体所做的特定更改?

EF Code First学习

code first提示已有打开的与此 Command 相关联的 DataReader,必须首先将它关闭解决方法

如何在 EF Core Code First 中自定义迁移生成?

使用 EF Code First 控制属性唯一性的最佳方法