1

2 つのリンク テーブルによってリンクされている 2 つのテーブル間にエンティティ関係を設定できるかどうかを調べようとしています。それが可能かどうかさえわかりません。

書店のデータベースを想像してみてください。あり、テーブル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か? 私は既存のテーブルでこれを行っているので、これはデータベース優先ですが、他の実装情報がおそらく役立つでしょう。

追加情報が役立つ場合があります。以下は、セクション内のすべての本をそのセクションでランク付けして返すサンプル クエリです (ランキングがより明確になるようにs を にBestSellerIndex変換しています)。null999

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
4

1 に答える 1

1

あなたの例を読んで、あなたがこれでどこに行こうとしているのかがわかります。私の意見では、これはおそらく Entity Framework へのハイブリッド アプローチが最適なケースです。さまざまなモデリング戦略 (「データベース ファースト」、「モデル ファースト」、「コード ファースト」) は明確に名前が付けられていません。たとえば、既存のデータベースでも Code-First を使用できます。Code-First とは、「モデル クラス」がデザイナーではなくコードを通じて定義されることを意味します。Code-First はデータベースを作成できますが、既存のデータベースでも問題なく機能するため、「ハイブリッド アプローチ」となります。

このドメイン モデルは、Fluent API を散りばめた Code-First を使用して、より単純に煮詰めたものです。

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 モデル デザイナーを使用して同じ結果を達成できる可能性がありますが、そこにあるすべてのオプションに精通しているわけではありません。この方法を使用すると、より正確に制御できます。最終結果を超えてください(データベースファーストデザイナーは、それが管理するクラスを作成するため、簡単に変更できません)。

于 2013-11-04T06:27:01.563 に答える