0

www.ASP.net Web サイトから Mvc Music Store チュートリアルを実行しています。

Entity Framework がどのようにテーブルを作成したか、およびそれらのラムダ式がどのように機能するかを理解するのに問題があります。私は EF と Lambda の基本を知っており、このシリーズの以前のチュートリアルを行っています。

私の質問は、チュートリアルのパート 4 に関連しています:パート 4: モデルとデータ アクセス モデルに は、以下のように、アーティスト、ジャンル、およびアルバムの 3 つのクラスがあります。

public class Artist
{
    public int ArtistId { get; set; }
    public string Name { get; set; }
}
public partial class Genre
{
    public int      GenreId     { get; set; }
    public string   Name        { get; set; }
    public string   Description { get; set; }
    public List<Album> Albums   { get; set; }
}
public class Album
{
    public int      AlbumId     { get; set;}
    public int      GenreId     { get; set; }
    public int      ArtistId    { get; set; }
    public string   Title       { get; set; }
    public decimal  Price       { get; set; }
    public string   AlbumArtUrl { get; set; }
    public Genre    Genre       { get; set; }
    public Artist   Artist      { get; set; }
}

ただし、EF によって作成された各テーブルの次の列のみが表示されました。

アーティスト表:ArtistId, Name

ジャンル表:GenreId, Name, Description

アルバム テーブル:AlbumId, GenreId, ArtistId, Title, Price, AlbumArtUrl

混乱 1

List<Album> Albumsアーティストテーブルは問題ありませんが、ジャンルテーブルにはクラス定義から何もありません。アルバム テーブルpublic Genre Genreにあり、public Artist Artist欠落しています。

以下は、SampleData.cs ファイルのデータベースに既定のデータを追加するステートメントです。

new Album 
{ 
    Title = "A Copland Celebration, Vol. I", 
    Genre = genres.Single(g => g.Name == "Classical"), 
    Price = 8.99M, 
    Artist = artists
        .Single(a => a.Name == "Aaron Copland & London Symphony Orchestra"), 
    AlbumArtUrl = "/Content/Images/placeholder.gif" 
}

質問

データベーステーブルにジャンルやアーティストなどの名前のフィールドがありませんか?? GenreId と ArtistId は挿入されませんが、データベースの Album テーブルにはこれらの値が取り込まれます。???

混乱 2

StoreControllerのBrowseアクションメソッドで、

// Retrieve Genre and its Associated Albums from database
var genreModel = storeDB.Genres.Include("Albums").Single(g => g.Name == genre);

ここでインクルードがどのように機能するかわかりません。Genres モデル クラスには List of Albums フィールドがありますが、データベースにはありません。include() がそこにアルバムのリストを保存する可能性があると推測できます。

質問

しかし、Include メソッドに「Albums」パラメーターがある理由がわかりません。DbContextAlbums の 2 つのリストがあり、1 つは Genre モデル クラスにあり、もう 1 つはEFの派生クラスにあります。このステートメントは、一致するジャンルのアルバムのみをどのように返しますか??

どんな助けでも大歓迎です。ありがとう

4

1 に答える 1

2

アーティストテーブルは問題ありませんが、ジャンルテーブルにはクラス定義のリストアルバムについては何もありません。アルバムテーブルにパブリックジャンルジャンルとパブリックアーティストアーティストがありません。

データベーステーブルにGenreやArtistのような名前のフィールドはありませんか?GenreIdとArtistIdは挿入されませんが、データベースのAlbumテーブルにはこれらの値が入力されます。

外部キープロパティ(ArtistIDおよびGenreID)は、EFナビゲーションプロパティを介して処理されるため、直接アクセスする必要はありません。アーティストやジャンルを設定するだけで、残りはEFが処理します。

およびプロパティはナビゲーションプロパティですGenreArtistこれらは実際にはデータベースに保存されていません。これは、関連するジャンルエンティティとの関連ArtistエンティティAlbumにアクセスしたり、ジャンルに関連するすべてのアルバムにアクセスしたりするための方法です。

たとえばArtist、エンティティのプロパティにアクセスすると、 EFが実行しているのは、アルバムにリストされているArtistIDを持つテーブル内の情報を提供することです。AlbumArtist

たとえば、AlbumAがあり、GenreAが1つとArtistAが1つあります。すべての情報をテーブルに保存するのではなく、情報を個別のテーブルに分割して、ストレージと再利用性を向上させます。これで、コードにAlbumAが含まれましたが、関連するGenreAの名前にアクセスしたいとします。使用するもの:

AlbumA.Genre.Name

これにより、アルバムテーブルに移動します。GenreIdを取得し、Genreテーブルに移動して、そのIDを持つGenreを返し、nameプロパティを指定します。これにより、すでに持っているアルバムのIDでジャンルを取得する関数を作成する手間が省け、コードが読みやすくなります。

しかし、Includeメソッドに「Albums」パラメーターがある理由がわかりません。アルバムのリストは2つあり、1つはジャンルモデルクラスにあり、もう1つはDbContextforEFから派生したクラスにあります。このステートメントは、ジャンルが一致するアルバムのみをどのように返しますか?

Include関数が行うことは、エンティティを熱心にロードすることです。それについての良い情報については、このブログ投稿を参照してください。

Genreオブジェクトをロードすると、Genreテーブルの情報のみがロードされます。関連するアルバムにアクセスする場合、EFは追加のデータベース呼び出しを行う必要があります。これはパフォーマンス上の理由で非常に悪い場合があるため、includeを使用すると、データベースに何度もアクセスするのではなく、1回の呼び出しで結合を実行して関連するすべてのデータを取得できます。

ナビゲーションプロパティとは何か、およびそれらがどのように機能するかについてのいくつかの追加リソース:

  1. ナビゲーションプロパティとは
  2. ナビゲーションプロパティの使用を開始する
于 2013-03-03T19:57:22.847 に答える