簡體   English   中英

如果table1包含fk到table2的同一列的多個字段,如何從一個表創建多個外鍵到另一個表

[英]How to create multiple foreign keys from one table to another if table1 contains multiple fields with fk to the same column of table2

我有“info”表,其中一些字段指向“file_uploads”表的“id”列。 另外我用fk到“file_uploads”的第三個表,讓我們稱之為“another_table”。 如何描述EF流暢api中的關系以使用Linq Join或Include Queries?

InfoRecord {
    public long Id {get; set;}
    public long File1Id {get; set;}
    public long File2Id {get; set;}
    public long File3Id {get; set;}

    public List<FileUploadRecord> Files {get; set;}
}

FileUploadRecord {
    public long Id {get; set;}
    public long Url {get; set;}

    public InfoRecord Info {get; set;}
}

AnotherTableRecord {
    public long Id {get; set;}
    public long ImageId {get; set;}

    public long FileUploadRecord Image { get; set; }
}

我知道我可以使用join創建簡單的原始sql查詢,它可以工作,但它不適用於Linq .Include或.Join。 我試圖通過不同的方式來解決它,因為EF拋出關於壞FK關系的錯誤。

我想你需要稍微調整你的模型。 現在, InfoRecord表有三列指向文件表。 問題是:如果明天你需要支持更多文件怎么辦? 添加更多列不是最佳選擇。 解決這個問題的過程就是所謂的數據庫規范化

如果InfoRecordFileUpload上需要“幾列指向id”,則您具有one-to-many關系 - 一個InfoRecord可以包含一個或多個文件。 我們可以使用3個表實現規范化:

1 - FileUpload (實際文件,最基本的實體。這里沒有關系。)

public class FileUpload
{
    public long Id { get; set; }

    public string FileName { get; set; }

    public string FilePath { get; set; }
}

2 - InfoRecord - 作為您的問題,InfoRecord可以包含許多文件:

public class InfoRecord
{
    public long Id { get; set; }

    public string Title { get; set; }

    public ICollection<FileUploadRecord> Files { get; set; }
}

最后,將它們“膠合”在一起的實體:

3 - FileUploadRecord - 它有一個FKFileUploadInfoRecord

public class FileUploadRecord
{
    public long Id { get; set; }

    // FK to InfoRecord. Usefull for update scenarious
    // without having to load the whole entity.
    public long InfoRecordId { get; set; }

    public InfoRecord InfoRecord { get; set; }

    // FK To the actual file upload
    public long FileId { get; set; }

    public FileUpload FileUpload { get; set; }
}

然后你可以使用FluentAPI配置它,如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    // Configure the Entity that "glues" InfoRecord and FileUploads. 
    // One InfoRecord can have many files, so we need a table to store that relationship.
    modelBuilder.Entity<FileUploadRecord>()
        .HasOne(s => s.InfoRecord)
        .WithMany(g => g.Files)
        .HasForeignKey(s => s.InfoRecordId);

    modelBuilder.Entity<FileUploadRecord>()
        .HasOne(p => p.FileUpload)
        .WithMany()
        .HasForeignKey(p => p.FileId);
}

並且使用.Include查詢就像你想要的那樣現在很簡單。 下面的查詢加載所有InfoRecords與每個相應的文件。

var recordsWithFiles = context.InfoRecords
                    .Include(p => p.Files)
                    .ThenInclude(p => p.FileUpload);

這就是數據庫架構的樣子: 在此輸入圖像描述

根據“another_table”,看起來它是一個簡單one-to-one關系,因此,您可以使用普通的EF核心約定 當然。 .Include也在這里工作。

public class AnotherTableRecord
{
    public long Id { get; set; }

    // FK To the actual file upload
    public long ImageId { get; set; }

    public FileUpload Image { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM