【发布时间】:2022-01-09 15:45:55
【问题描述】:
我有一个文件表,我想在其他 2 个表中引用它。 每个文件都是其中一个表独有的,这意味着我的外键在至少一个链接表中没有实体,某些文件可能有一个填充键,它根本没有链接到任何实体(因为它将是稍后装箱)。
关系:(1 -> n)
Item <- File -> Image
这会导致 insert/SaveChanges 上的外键异常,因为数据库无法找到链接的实体。
我搜索了解决方案,但找不到任何解决此问题的文章,并且我提出的解决方案至少有一种代码异味。
问题:如何链接这 3 个表而不会出现数据库异常并产生代码/数据库气味?
或者可能是整个数据架构有问题,我应该尝试一些不同的东西(如果有的话)?
我想出但不想使用的解决方案:
- 没有外键,但有一个新查询
- 使用仅包含链接实体(文件 -> 链接 -> 项目)的中间表
- 将
Files表拆分为ItemFiles和ImageFiles(听说这是DB 气味)
其他信息:
- .NET Core 3.1
- EF Core:最新
- 数据库:Sqlite
缩短模型:
public class FileData
{
public Item Item { get; set; }
public ImageData Image { get; set; }
public Guid Id { get; set; }
public string HashKey { get; set; }
// ...
}
public class Item
{
public FileData[] Files { get; set; }
public Guid Id { get; set; }
public string HashKey { get; set; }
// ...
}
public class ImageData
{
public FileData[] Files { get; set; }
public Guid Id { get; set; }
public string HashKey { get; set; }
// ...
}
数据库配置:
public class FileDataConfiguration : IEntityTypeConfiguration<FileData>
{
public void Configure(EntityTypeBuilder<FileData> builder)
{
builder.HasKey(file => file.Id);
builder.HasIndex(file => file.HashKey);
// ...
}
}
public class ItemConfiguration : IEntityTypeConfiguration<Item>
{
public void Configure(EntityTypeBuilder<Item> builder)
{
builder.HasKey(item => item.Id);
builder.HasMany(item => item.Files)
.WithOne(file => file.Item)
.IsRequired(false)
.HasForeignKey(file => file.HashKey)
.IsRequired(false)
.HasPrincipalKey(item => item.HashKey);
builder.HasIndex(file => file.HashKey);
// ...
}
}
public class ImageDataConfiguration : IEntityTypeConfiguration<ImageData>
{
public void Configure(EntityTypeBuilder<ImageData> builder)
{
builder.HasKey(image => image.Id);
builder.HasMany(image => image.Files)
.WithOne(file => file.Image)
.IsRequired(false)
.HasForeignKey(file => file.HashKey)
.IsRequired(false)
.HasPrincipalKey(image => image.HashKey);
builder.HasIndex(image => image.HashKey);
// ...
}
}
此代码引发异常
// both examples throw an exception, independent of each other
//example 1:
dbContext.Files.Add(
new File(){
HashKey="1"
}
);
dbContext.SaveChanges();
//example 2:
dbContext.Files.Add(
new File(){
HashKey="2"
}
);
dbContext.Items.Add(
new Item(){
HashKey="2"
}
);
dbContext.SaveChanges();
【问题讨论】:
-
您还应该显示导致异常的代码。
-
在我添加了一个没有链接的实体后,SaveChanges 上抛出了异常
-
我假设
FIle是FileData?无论如何,您不要输入“没有链接”的实体。Hashkey是外键。 -
但是我需要一个包含所有文件及其哈希键的列表(出于算法原因),并且我想通过哈希键将项目链接到此列表。由于并非所有文件都是项目/图像,因此我正在寻找一种解决方案来使用 EF Core 表示此链接。如果这是一个外键或不是次要的,我只是在寻找正确的解决方案来表示这种关系。这意味着,不存储“未链接”的文件是不可能的。
标签: c# sqlite .net-core entity-framework-core ef-core-3.1