我试图弄清楚是否可以在两个表之间建立实体关系,这两个表由两个链接表链接。我不确定它是否可能。
想象一下书店数据库。有Books
个表和Sections
个表。这些表通过名为SectionBooks
的链接表连接(多对多,因为一本书可能在多个部分中)。但商店中的每个部分都会有一个畅销书列表,这是该部分热门书籍的非详尽排名。这将在BestSellers
。
数据可能如下所示:
[Books]
BookId Title Author
1000 Allegiant Roth
1001 The Book Thief Zusak
1002 Mocking Jay Collins
1003 Fan Girl Rowell
1004 I am Malala Yousafzai
[Sections]
SectionId Name
1 Fiction
2 Young Adult
[SectionBooks]
SectionId BookId
2 1000
2 1001
2 1002
2 1003
2 1004
[BestSellers]
SectionId BookId BestSellerIndex
2 1000 1
2 1001 2
2 1002 3
您如何对此进行编码,以便从SectionBooks
和BestSellers
获取数据?我正在使用现有的表,所以这将是数据库优先,但任何其他实现信息可能会有所帮助。
额外信息可能有所帮助。这是一个示例查询,它会在按BestSellerIndex
排名的部分中返回所有图书(我将null
转换为999
,以便排名更明显。)
SELECT
ISNULL(BestSellerIndex, 999) AS BestSellerIndex
SectionBooks.SectionId,
Books.Id, Books.Title, Books.Author
FROM Books
INNER JOIN SectionBooks ON Books.BookId = SectionBooks.BookId
LEFT OUTER JOIN BestSellers BestSellers ON Book.BookId = BestSellers.BookId
WHERE SectionBooks.SectionId = 2 AND (BestSellers.SectionId = 2 OR BestSellers.SectionId IS NULL)
ORDER BY BestSellerIndex, Title DESC
这将产生以下数据集:
BestSellerIndex SectionId BookId Title Author
0 2 1000 Allegiant Roth
1 2 1001 The Book Thief Zusak
2 2 1002 Mocking Jay Collins
999 2 1003 Fan Girl Rowell
999 2 1004 I am Malala Yousafzai
答案 0 :(得分:1)
通过你的例子,我可以看到你试图用它去哪里。在我看来,这是一个案例,你可能最好通过实体框架的混合方法服务。不同的建模策略(“数据库优先”,“模型优先”,“代码优先”)的命名并不十分明确。例如,即使使用现有数据库,也可以使用Code-First;所有Code-First意味着“模型类”是通过Code而不是设计者定义的。虽然Code-First可以创建一个数据库,但它可以与现有数据库一起使用,因此是“混合方法”。
使用Code-First简化了这个领域模型,并使用了Fluent API。
使用Code-First建模,您的模型非常简单:
public class Book()
{
public int BookId {get;set;}
public string Title {get;set;}
public string Author {get;set;}
public virtual ICollection<Section> Sections {get;set;}
}
public class Section()
{
public int SectionId {get;set;}
public string Name {get;set;}
public virtual ICollection<Book> Books {get;set;}
}
public class BestSeller()
{
public int BestSellerIndex {get;set;}
public Section Section {get;set;}
public Section Book {get;set;}
}
然后您使用一些Fluent API来确保以正确的方式映射表,例如......
// Define the BestSeller to have a composite key from the 2 joined tables
modelBuilder.Entity<BestSeller>().HasKey(t =>
new {t.Section.SectionId, t.Book.BookId});
// Define the Many to Many mapping
modelBuilder.Entity<Book>()
.HasMany(b => b.Section)
.WithMany(s => s.Book)
.Map(
m => {
m.MapLeftKey("BookId");
m.MapRightKey("SectionId");
m.ToTable("SectionBooks");
});
您可能需要其他Fluent API以确保表名称是多元化的,并且表格架构匹配,更多信息在MSDN上
从这里开始,您可以简单地枚举集合......即bestSellers = context.BestSellers();
foreach (var bestSeller in bestSellers)
{
var title = bestSeller.Book.Title;
var section = bestSeller.Section.Name;
...
}
这可能会进一步优化或调整,您可以通过使用Database-First模型设计器来获得相同的结果,但我不熟悉那里的所有选项,这种方法可以为您提供更多更精确地控制最终结果(因为Database-First Designer创建了它管理的类,您无法轻松更改)。