我使用EF Core 7.0中的功能,该功能允许使用带有参数化构造函数的实体,如here所述.

然而,当涉及到 Select 使用哪个构造函数时,我不理解EF Core的一些行为.

例如,我有一个具有只读ID的实体,因此有一个创建构造函数,它生成id和一个以ID为参数的重构构造函数.

public class Poll
{
    public Guid Id { get; }
    public string Name {get;set;}
    public DateTime ExpirationDate { get; set; }
    public List<Vote> Votes { get; set; }
    public List<DateTime> dates {get;set;} = new List<DateTime>();

    public Poll(string name, List<DateTime> dates) : this(
        Guid.NewGuid(), 
        name,
        new List<Vote>(), 
        dates, 
        DateTime.UtcNow.AddMonths(2)
        )
    {
    }

    public Poll(Guid id, string name, List<DateTime> dates, DateTime expirationDate)
    {
        Name = name;
        Id = id;
        Dates = dates;
        ExpirationDate = expirationDate;
    }





}

具有以下模型绑定:

       modelBuilder.Entity<Poll>(entity =>
        {
            entity.HasKey(poll => poll.Id);
            entity
                .Property(poll => poll.Id)
                .ValueGeneratedNever();
            entity.Property(poll => poll.Name);
            entity.Property(poll => poll.Dates);
            entity.Property(poll => poll.ExpirationDate);
        });

当查询这个实体时,EF Core将调用第一个(创建)构造函数,而我希望(根据文档,我认为这是合乎逻辑的),它宁愿使用第二个(重构)构造函数. 根据文档,它为什么不使用带有每个映射属性的参数的构造函数:

但是,如果EF Core找到其参数名称和类型与映射属性的参数名称和类型匹配的参数化构造函数,则它将使用这些属性的值调用该参数化构造函数,而不会显式设置每个属性.

编辑:通过删除第一个构造函数进行了试验,它抛出了一个异常,说明votes参数无法绑定到属性.取下它的时候,它起作用了.然而,当添加回我的第一个构造函数时,EF仍然使用它而不是另一个,所以问题仍然存在.

推荐答案

GitHub上的源代码显示,使用标量参数最少的构造函数-you don't have services, only scalar property parameters.

从实体构造函数 Select 所涉及的ConstructorBindingFactory类的源代码:

// Trying to find the constructor with the most service properties
// followed by the least scalar property parameters

A unit test in the source code demonstrates this behavior.
In below example, the constructor with 2 parameters will be chosen.

public void Binds_to_least_parameters_if_no_services()
{
    var constructorBinding = GetBinding<BlogSeveral>();

    Assert.NotNull(constructorBinding);

    var parameters = constructorBinding.Constructor.GetParameters();
    var bindings = constructorBinding.ParameterBindings;

    Assert.Equal(2, parameters.Length);
    Assert.Equal(2, bindings.Count);

    Assert.Equal("title", parameters[0].Name);
    Assert.Equal("id", parameters[1].Name);

    Assert.Equal("Title", bindings[0].ConsumedProperties.First().Name);
    Assert.Equal("Id", bindings[1].ConsumedProperties.First().Name);
}

private class BlogSeveral : Blog
{
    public BlogSeveral(string title, int id)
    { }

    public BlogSeveral(string title, Guid? shadow, int id)
    { }

    public BlogSeveral(string title, Guid? shadow, bool dummy, int id)
    { }
}

关于带有List<Votes> votes参数的构造函数上的错误,您会明白这一点,因为EF Core不能使用构造函数设置导航属性,正如您链接的文档中所提到的那样.

Csharp相关问答推荐

火鸟DBC驱动程序未加载ADF DLC

ß != ss与ICU进行不区分大小写的比较

更新数据库中的对象失败,原因是:Microsoft. EntityFrame Core. GbUpdateConcurrencyResponse'

如何保持主摄像头视角保持一致?

在. NET Core 8 Web API中,当为服务总线使用通用消费者时,如何防止IServiceProvider被释放或空?"

为什么这个Reflection. Emit代码会导致一个DDL ViolationException?

解析需要HttpClient和字符串的服务

"virtual"修饰符对接口成员有什么影响?

不仅仅是一个简单的自定义按钮

HttpConext.Request.Path和HttpConext.GetEndpoint()之间的差异

在允许溢出的情况下将小数转换为长

ASP.NET核心MVC SqlException:违反主键约束';PK_USER';.无法在对象';数据库中插入重复的密钥.用户';

异步实体框架核心查询引发InvalidOperation异常

BlockingCollection T引发意外InvalidOperationException

如何在不复制或使用输出的情况下定义项目依赖

JsonPath在Newtonsoft.Json';S实现中的赋值

此异步方法在重写方法中缺少等待运算符警告

如何在特定环境中运行dotnet测试?

未显示详细信息的弹出对话框

如何将 colored颜色 转换为KnownColor名称?