我有一個檔案表,我想在其他 2 個表中參考它。每個檔案都是其中一個表獨有的,這意味著我的外鍵在至少一個鏈接表中沒有物體,某些檔案可能有一個填充鍵,它根本沒有鏈接到任何物體(因為它將是稍后裝箱)。
關系:(1 -> n)
Item <- File -> Image
這會導致 insert/ 上的外鍵例外SaveChanges,因為資料庫無法找到鏈接的物體。
我搜索了一個解決方案,但找不到任何解決此問題的文章,而且我提出的解決方案至少有一個代碼異味。
問題:如何鏈接這 3 個表而不會出現資料庫例外并產生代碼/資料庫氣味?
還是整個資料架構有問題,我應該嘗試一些不同的東西(如果有的話)?
我想出但不想使用的解決方案:
- 沒有外鍵,但有一個新查詢
- 使用只有鏈接物體的物體的中間表(檔案->鏈接->專案)
- 把
Files桌子分成ItemFiles和ImageFiles(我聽說這是 DB 的味道)
其他資訊:
- .NET 核心 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();
uj5u.com熱心網友回復:
通常,您的FileData物體應包含和物體的Guid外鍵,而不僅僅是導航屬性,即和。例如:ItemImageDataGuid ItemIdGuid ImageId
public class FileData
{
public Guid ItemId { get; set;}
public Item Item { get; set; }
public Guid ImageId {get; set; }
public ImageData Image { get; set; }
public Guid Id { get; set; }
public string HashKey { get; set; }
// ...
}
同樣在 Fluent Api 中同時配置兩者時Item,ImageData此配置應該足夠了
builder.HasMany(item => item.Files)
.WithOne(file => file.Item)
.IsRequired(false)
.OnDelete(DeleteBehavior.NoAction);
uj5u.com熱心網友回復:
最后我決定放棄外鍵,因為我不需要更新其他物體并手動啟動檔案查詢。似乎不可能將檔案添加為屬性,因為錯誤一直被拋出(我嘗試了這個解決方案)。
使用的約束串列:Item.Id => Key Item.Hash => Indexed, Unique
Image.Id => 關鍵 Image.Hash => 索引,唯一
File.Id => Key File.Hash => 索引,不唯一
我決定保留 Item 和 Image 的 ID 的原因之一是其他物體主要通過 ID 參考這些,而不是哈希,并且哈希可能會更改,需要進行大量更新。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/410116.html
標籤:
