EF6表拆分和异常“ Re freentialConstraint中的从属属性映射到商店生成的列。列:“ Id”。”

问题描述 投票:0回答:1

一段时间以来,我一直在域设计中遵循Object Calisthenics中的“一流收藏”规则。为了避免创建无用的“集合”表,我使用了Entity Framework中的table splitting配置。

但是如果出于某种原因,我有一个Parent类,除了其ID和子级集合之外,没有其他属性,则会出现异常:

InvalidOperationException:ReferentialConstraint中的从属属性被映射到商店生成的列。列:“ Id”。

奇怪的是,数据库创建正确,可以从中查询,但是无法保存。

如果我只是简单地向Parent添加另一个属性,问题就会消失,这更加奇怪。

我将其范围缩小到一个非常简单的测试用例:

Program.cs

class Program
{
    static void Main(string[] args)
    {
        using (var context = new MyContext(new DropCreateDatabaseAlways<MyContext>()))
        {
            context.Set<Parent>().Find(1);
        }

        using (var context = new MyContext(new CreateDatabaseIfNotExists<MyContext>()))
        {
            context.Set<Parent>().Add(
                new Parent()
                {
                    ChildrenCollection = new ChildrenCollection()
                    {
                        List = new List<Child>() { new Child() }
                    }
                });
            context.SaveChanges(); // Exception thrown here
        }
    }
}

public class Parent
{
    public int Id { get; set; }
    public virtual ChildrenCollection ChildrenCollection { get; set; }
}

public class ChildrenCollection
{
    public int Id { get; set; }
    public virtual IList<Child> List { get; set; }
}

public class Child
{
    public int Id { get; set; }
}

Context

public class MyContext : DbContext
{
    public MyContext(IDatabaseInitializer<MyContext> dbInitializer)
        : base(nameOrConnectionString: GetConnectionString())
    {
        Database.SetInitializer(dbInitializer);
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new ChildrenCollectionConfiguration());
        modelBuilder.Configurations.Add(new ParentConfiguration());

        base.OnModelCreating(modelBuilder);
    }

    private static string GetConnectionString()
    {
        return @"Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=TestEntityFramework;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=True;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;MultipleActiveResultSets=true;";
    }
}

配置

public class ParentConfiguration : EntityTypeConfiguration<Parent>
{
    public ParentConfiguration()
    {
        HasRequired(x => x.ChildrenCollection)
            .WithRequiredPrincipal();
    }
}

public class ChildrenCollectionConfiguration : EntityTypeConfiguration<ChildrenCollection>
{
    public ChildrenCollectionConfiguration()
    {
        #region Configure Table Splitting

        var parentTable = typeof(Parent).Name;

        ToTable(parentTable);

        HasMany(x => x.List)
            .WithRequired()
            .Map(x =>
            {
                x.MapKey(string.Concat(parentTable, "_Id"));
            });

        #endregion
    }
}
c# entity-framework-6 ef-code-first ef-code-first-mapping table-splitting
1个回答
0
投票

配置顺序很重要,父级配置必须优先。

直接从DbContext类进行配置时,从父级到子级保持配置的逻辑顺序是很自然的,但是当您单击separate the config using EntityTypeConfiguration<TEntity>时,情况可能并非如此。

这似乎是此特定情况下Entity Framework中的错误,因为它在大多数情况下都有效。

为了确保它始终有效,只需先为层次结构中较高级别的类调用配置。

EntityTypeConfiguration<TEntity>
© www.soinside.com 2019 - 2024. All rights reserved.