[英]How to create multiple foreign keys from one table to another if table1 contains multiple fields with fk to the same column of table2
I have "info" table with some fields that point to "id" column of "file_uploads" table. 我有“info”表,其中一些字段指向“file_uploads”表的“id”列。 Also I third table with fk to "file_uploads", lets call it "another_table". 另外我用fk到“file_uploads”的第三个表,让我们称之为“another_table”。 How can I describe relationships in EF fluent api to use Linq Join or Include Queries? 如何描述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; }
}
I know that I can create simple raw sql query with join and it will work, but It doesn't work with Linq .Include or .Join. 我知道我可以使用join创建简单的原始sql查询,它可以工作,但它不适用于Linq .Include或.Join。 I've tried to solve it by different ways, bu EF throw errors about bad FK relations. 我试图通过不同的方式来解决它,因为EF抛出关于坏FK关系的错误。
I think you need to tweak your models a little bit. 我想你需要稍微调整你的模型。 Right now, the InfoRecord
table has three columns pointing to the files table. 现在, InfoRecord
表有三列指向文件表。 The problem with that is: What if tomorrow you need to support more files? 问题是:如果明天你需要支持更多文件怎么办? Adding more columns is not optimal. 添加更多列不是最佳选择。 The process of fixing this is what's called Database Normalization . 解决这个问题的过程就是所谓的数据库规范化 。
If InfoRecord
needs "several columns to point to an id" on FileUpload
, you have a one-to-many
relationship - One InfoRecord
can have one or more files. 如果InfoRecord
在FileUpload
上需要“几列指向id”,则您具有one-to-many
关系 - 一个InfoRecord
可以包含一个或多个文件。 We can achieve normalization using 3 tables: 我们可以使用3个表实现规范化:
1 - FileUpload
(the actual files, most basic entity. No relationships here.) 1 - FileUpload
(实际文件,最基本的实体。这里没有关系。)
public class FileUpload
{
public long Id { get; set; }
public string FileName { get; set; }
public string FilePath { get; set; }
}
2 - InfoRecord
- As your question, a InfoRecord can have many files: 2 - InfoRecord
- 作为您的问题,InfoRecord可以包含许多文件:
public class InfoRecord
{
public long Id { get; set; }
public string Title { get; set; }
public ICollection<FileUploadRecord> Files { get; set; }
}
And lastly, the entity that "glues" them together: 最后,将它们“胶合”在一起的实体:
3 - FileUploadRecord
- It has an FK
to FileUpload
and to InfoRecord
3 - FileUploadRecord
- 它有一个FK
到FileUpload
和InfoRecord
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; }
}
Then you can configure it using the FluentAPI
like this: 然后你可以使用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);
}
And to query using .Include
like you wanted is easy now. 并且使用.Include
查询就像你想要的那样现在很简单。 The query below loads all InfoRecords
with each respective files. 下面的查询加载所有InfoRecords
与每个相应的文件。
var recordsWithFiles = context.InfoRecords
.Include(p => p.Files)
.ThenInclude(p => p.FileUpload);
This is how the DB schema will look like: 这就是数据库架构的样子:
As per the "another_table", looks like it's a simple one-to-one
relationship so, you can just use plain EF Core Conventions for it. 根据“another_table”,看起来它是一个简单one-to-one
关系,因此,您可以使用普通的EF核心约定 。 Of course .Include
also works here. 当然。 .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.