Entity Framework 核心数据库优先 - 多个外键对应一个 table

Entity Framework Core Database First - Multiple Foreign keys to one table

背景资料

我目前正在使用数据库优先实现的 EF Core。

当前table秒

Fizz
{
    [Id] INT
    [Category] varchar
    [Value] varchar
}

Buzz
{
    [Id] UniqueIdentifier
    [TypeId1] INT
    [TypeId2] INT
    CONSTRAINT [FK_Buzz_Fizz_1] FOREIGN KEY ([TypeId1] REFERENCES [Fizz][Id]) 
    CONSTRAINT [FK_Buzz_Fizz_2] FOREIGN KEY ([TypeId2] REFERENCES [Fizz][Id])
}

Fizz 当前执行查找 table。这样做允许使用单个数据存储库按类别查找不同的值。

Buzz 是一个 table,它有两个不同的类型值要存储,例如TypeId1 可以是 Fizz 中作为 (id, Brands, Nestle) 存在的品牌,TypeId2 可以是 Fizz 中作为 (id, Flavors, Grape) 存在的风味。

问题

我搭建数据库以创建数据模型。 当运行应用程序出现以下情况时:

InvalidOperationException: Unable to determine the relationship represented by navigation property 'Buzz.TypeId1' of type 'Fizz'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

我想到的一个解决方案是将此查找 table (Fizz) 分解为多个 table,这样就可以通过不将重复类型用于外键来解决引用问题。

这将需要重新处理当前数据存储库的逻辑,以访问多个 table 或拆分为多个数据存储库。

另一种解决方案是修改生成的 DBContext 并在 DataModel 上使用 DataAnnotations。我想避免这样做,因为将来会重新生成上下文和模型,并且这些更改将被覆盖。

有没有一种方法可以从具有多个外键的 table 生成数据模型到单个 table 而无需修改生成的代码?

子孙后代:

使用数据库方法,可以完成数据库的脚手架以创建上下文和数据模型。

生成的数据模型(使用上面的示例表)看起来像这样 -

public partial class Buzz
{
    public Buzz()
    { }

    public Guid Id { get; set; }
    public int TypeId1 { get; set; }
    public int TypeId2 { get; set; }

    public Fizz TypeId1Fizz { get; set; }
    public Fizz TypeId2Fizz { get; set; }
}


public partial class Fizz
{
    public Fizz()
    { }

    public int Id { get; set; }
    public string Category { get; set; }
    public string Value { get; set; }

    public ICollection<Buzz> TypeId1Fizz { get; set; }
    public ICollection<Buzz> TypeId2Fizz { get; set; }
}

问题是无法解决 Buzz 中的关系。

解决方案

在数据库上使用脚手架时,所有模型都生成为指定文件夹的局部模型。我在脚手架创建的目录内的另一个目录中为 Buzz class 创建了一个部分(确保名称空间匹配 VS 喜欢将目录名称添加到名称空间并且部分不会匹配).

public partial class Buzz
{
    [NotMapped]
    public Fizz TypeId1Fizz { get; set; }
    [NotMapped]
    public Fizz TypeId2Fizz { get; set; }
}

但是 Leustherin 那么你就失去了使用 .Include 的能力! EntityFramework 不会为您创建 SQL 连接语句,因此您将不得不额外访问数据库以获取查找值!

要解决此问题,请覆盖数据存储库的 Get 或 GetAll 函数并创建您自己的连接语句。

为什么我选择这个解决方案

可维护性。

只要重新生成数据模型而不是出现运行时错误,现在就会出现编译错误,提醒开发人员从生成的数据模型中删除额外的属性。

自动生成的文件没有其他修改。

未对架构进行重大更改以适应更改。

我会尽力保持更新。