迁移最初有效,但现在产生奇怪的错误

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

长话短说,我使用 EF Core 8 成功进行了初始迁移。但是,很快我到处发现了一些相当小的问题,并尝试修改它们,但此后尝试进行新的迁移最终会出错并出现非常奇怪的错误。这很令人费解,因为最初的迁移很顺利,但现在却无法正常工作。

我做了一个单独的项目,并尝试一一添加模型类,直到它停止工作。

这是项目仍然有效的设置:

internal class Dictionary
{
    public string Name { get; set; }
    public bool IsEnabled { get; set; }
    public ICollection<DictionaryEntry> Entries { get; set; }
}

internal class DictionaryEntry
{
    public string Name { get; set; }
    public bool IsEnabled { get; set; }
    public Dictionary Dictionary { get; set; }
}

internal abstract class DictionaryEntry<TValue>: DictionaryEntry
{
    public TValue Value { get; set; }
}

internal abstract class GroupedEntry<TValue, TEntryGroup>: DictionaryEntry<TValue>
    where TEntryGroup : DictionaryEntry
{
    public virtual TEntryGroup EntryGroup { get; set; }
}

internal class EntryGroup<TEntry>: DictionaryEntry
    where TEntry : DictionaryEntry
{
    public virtual ICollection<TEntry> Entries { get; set; } 
    public virtual EntryGroup<TEntry> Parent { get; set; }
    public virtual ICollection<EntryGroup<TEntry>> Children { get; set; }
}

internal class EntryGroup<TGroupEntry, TEntry>: EntryGroup<TEntry>
    where TGroupEntry : DictionaryEntry
    where TEntry : DictionaryEntry
{
    public virtual TGroupEntry GroupEntry { get; set; } = null!;
}

internal class EntryClassA: DictionaryEntry<uint>
{
    public virtual EntryClassB LinkedDocumentation { get; set; }
}

internal class EntryClassB: GroupedEntry<uint, EntryGroup_EntryClassAB>;

internal class EntryGroup_EntryClassAB: EntryGroup<EntryClassB, EntryClassA>

添加这些类会导致错误:

internal abstract class Entry_ClassCBase: GroupedEntry<uint, EntryGroup_ClassC>;
internal class Entry_ClassCGroup: Entry_ClassCBase;
internal class Entry_ClassC: Entry_ClassCBase;
internal class EntryGroup_ClassC: EntryGroup<Entry_ClassCGroup, Entry_ClassC>;

在这种特殊情况下,这是由于

无法创建类型为“”的“DbContext”。异常“无法确定“EntryGroup_ClassC.GroupEntry”和“Entry_ClassCGroup.EntryGroup”之间的一对一关系的从属方。要识别关系的从属方,请配置外键属性。如果这些导航不应该属于同一关系,请通过“OnModelCreating”中单独的方法链独立配置它们。有关更多详细信息,请参阅 https://go.microsoft.com/fwlink/?LinkId=724062。尝试创建实例时抛出。有关设计时支持的不同模式,请参阅 https://go.microsoft.com/fwlink/?linkid=851728

但是在主应用程序中,当第一次迁移成功创建时,模型已经包含了那些相同的类,所以我不明白错误的突然起源。我可以煞费苦心地把错误一一改正,但我当然不想这么做。我唯一的理论是,当我解决这些问题时,我可能会改组一些使模型工作的代码,但我不明白是哪些。

这是我的背景:

namespace Program
{
    sealed class CultureInfoConverter: ValueConverter<CultureInfo, string>
    {
        public CultureInfoConverter() : base(static (v) => v.Name, static (v) => CultureInfo.GetCultureInfo(v)) { }
    }

    internal partial class Context(DbContextOptions<Context> options): DbContext(options)
    {
        public DbSet<Dictionary> Dictionaries { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            _ = modelBuilder.
                HasCollation("en_natural", locale: "en-u-kn-true", provider: "icu", deterministic: false);
            _ = modelBuilder.UseHiLo(null);

            _ = modelBuilder.Owned<Oid>();
            _ = modelBuilder.Owned<Version>();

            _ = modelBuilder.Entity<Dictionary>().
                HasDiscriminator();
            _ = modelBuilder.Entity<Dictionary>().Property<uint>("RowVersion").
                IsRowVersion();
            _ = modelBuilder.Entity<DictionaryEntry>().
                HasDiscriminator();
            _ = modelBuilder.Entity<DictionaryEntry>().Property<uint>("RowVersion").
                IsRowVersion();
            _ = modelBuilder.Entity<Dictionary>().Property<ulong>("Id");
            _ = modelBuilder.Entity<DictionaryEntry>().Property<ulong>("Id");
        }
        protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
        {
            _ = configurationBuilder.Properties<string>().
                UseCollation("en_natural").
                AreUnicode();

            _ = configurationBuilder.Properties<CultureInfo>().
                HaveConversion<CultureInfoConverter>();
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => _ = optionsBuilder.UseExceptionProcessor();
    }
}
entity-framework-core
1个回答
0
投票

所以有几件事需要检查(我能想到的唯一的事情):

EF Core 可能会与复杂继承设置中的关系混淆,特别是一对一关系的哪一侧是依赖的。

EntryGroup_ClassC.GroupEntry
Entry_ClassCGroup.EntryGroup
似乎就是这种情况。也许尝试在
OnModelCreating
中显式设置外键以澄清映射。

然后继续复杂的继承问题 EF Core 通常需要您为一对一或一对多关系手动定义外键。我想说的是,检查

GroupedEntry
EntryGroup
类中的每个关系,并显式设置
HasForeignKey
或使用
WithOne/WithMany
确保每个映射尽可能清晰。

© www.soinside.com 2019 - 2024. All rights reserved.