背景信息
我目前正在使用数据库优先实现使用 EF Core。
当前表
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 目前充当查找表。这样做允许使用单个数据存储库按类别查找不同的值。
Buzz是一个表,它有两个不同的类型值要存储,例如TypeId1可以是品牌,它将存在于Fizz中(id,Brands,Nestle),TypeId2可能是存在于Fizz中的风味(id,Flavors,Grape)。
问题
我搭建数据库以创建数据模型。 运行应用程序时,会出现以下情况:
InvalidOperationException:无法确定类型为"Fizz"的导航属性"Buzz.TypeId1"表示的关系。手动配置关系,或使用"[NotMapped]"属性或使用"OnModelCreateing"中的"EntityTypeBuilder.Ignore"忽略此属性。
我想到的一个解决方案是将此查找表(Fizz)分解为多个表,这样就可以通过不将重复类型用于外键来解决引用。
这将需要重新设计当前数据存储库的逻辑,以访问多个表或拆分为多个数据存储库。
另一种解决方案是修改生成的DBContext,并在DataModel上使用DataAnnotations。我想避免这样做,因为上下文和模型将在将来重新生成,并且这些更改将被覆盖。
有没有办法从具有多个外键的表生成数据模型到单个表,而无需修改生成的代码?
对于后代:
使用数据库方法,完成数据库的基架来创建上下文和数据模型。
生成的数据模型(使用上面的示例表)如下所示 -
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 类创建了一个部分,该目录位于由脚手架创建的目录中(确保命名空间匹配 VS 喜欢将目录名称添加到命名空间,并且部分不会匹配)。
public partial class Buzz
{
[NotMapped]
public Fizz TypeId1Fizz { get; set; }
[NotMapped]
public Fizz TypeId2Fizz { get; set; }
}
但是路斯特林然后你就失去了利用的能力.包括嘶嘶声!EntityFramework 不会为您创建 SQL 连接语句,因此您必须额外访问数据库才能获得查找值!
若要解决此问题,请重写数据存储库的 Get 或 GetAll 函数,并创建自己的连接语句。
为什么我选择这个解决方案
可维护性。
每当重新生成 DataModel 而不是收到运行时错误时,现在都会出现编译错误,提醒开发人员从生成的数据模型中删除额外的属性。
对自动生成的文件没有其他修改。
没有进行重大的架构更改以适应更改。
我会尽我所能保持更新。