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 函数并创建您自己的连接语句。
为什么我选择这个解决方案
可维护性。
只要重新生成数据模型而不是出现运行时错误,现在就会出现编译错误,提醒开发人员从生成的数据模型中删除额外的属性。
自动生成的文件没有其他修改。
未对架构进行重大更改以适应更改。
我会尽力保持更新。
背景资料
我目前正在使用数据库优先实现的 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 函数并创建您自己的连接语句。
为什么我选择这个解决方案
可维护性。
只要重新生成数据模型而不是出现运行时错误,现在就会出现编译错误,提醒开发人员从生成的数据模型中删除额外的属性。
自动生成的文件没有其他修改。
未对架构进行重大更改以适应更改。
我会尽力保持更新。