2011-06-20 15 views
4

MVC MusicStoreを通してMVCを学習しながら頭を悩ましています。 Details ViewのModel.Artist.Nameにこのエラーがあります。MVC MusicStore Artist.Nameオブジェクトのリファレンスがオブジェクトのインスタンスに設定されていません

私のStorecontroller詳細メソッドは正常です。

public ActionResult Details(int id) 
    { 
     //returns and albums searched from the id 
     var albums = storeDB.Albums.Find(id); 
     return View(albums); 
    } 

そして、これは、価格のためにどのようにI出力ビュー

<li>Price : <%=Model.Price %></li> 
    <li>Artist : <%=Model.Artist.Name%></li> 

作品結構です、そしてそれが唯一のModel.Genre.NameとArtist.Nameのエラーが表示されます。私はこの問題に

Artist = artists.Single(a => a.Name == "Aaron Copland & London Symphony Orchestra") 

を引き起こした。しかし、この私の知識は何かを作るには弱すぎるsampledata.csでこれらのプロパティの宣言を疑っています。助けてください 。

さてさて、値は値が割り当てられている方法で、この

protected override void Seed(MusicStoreEntities context) 
    { 
     var artists = new List<Artist> 
     { 
      new Artist { Name = "Aaron Copland & London Symphony Orchestra" }, 
      etcetc 
     } 
     new List<Album> 
     { 
      new Album { Title = "ABC", Artist= artists.Single(g => g.Name == "Test")} 
     } 
    } 

テイク予告のように見えるクラスファイルからフェッチされ、私はModel.Title罰金(短い手としてモデル)にアクセスすることができ、 Model.Artist.Nameは私にそのエラーを引き起こしました。

は、よし

を解決し、それがアルバムのクラスのアーティストやジャンル宣言に仮想キーワードを追加することで動作するようになりました。しかし、私はまだ何が起こっているか分かりませんし、誰かに光を当てたいと思ってもらいたいと思います。私のアルバムのクラスで

、それは

public virtual Artist Artist { get; set; } 

どういうわけか、仮想キーワードを追加することによって、私はまだ「couldn解かれるジャンルやアーティストによって引き起こされるこの

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 MusicStore.cs StoreController.cs

MusicStoreEntities storeDB = new MusicStoreEntities(); 

    public ActionResult Details(int id) 
    { 
     //returns and albums searched from the id 
     var albums = storeDB.Albums.Find(id); 
     return View(albums); 
    } 

最後にサンプルデータ

namespace MvcMusicStore.Models 
{ 
    //represent entity framework , handle create ,read , update and del ops 
    public class MusicStoreEntities : DbContext 
    { 
     public DbSet<Album> Albums { get; set; } 
     public DbSet<Genre> Genres { get; set; } 
     public DbSet<Artist> Artists { get; set; } 

    } 
} 

と実装を使用して

namespace MvcMusicStore.Models 
{ 
    public class Album 
    { 
     public int AlbumId { get; set; } 
     public int GenreId { get; set; } 
     public int ArtistId { get; set; } 
     public string Title { get; set; } 

     public virtual Genre Genre { get; set; } 
     public virtual Artist Artist { get; set; } 
    } 
} 

Album.cs

、このように書きます
protected override void Seed(MusicStoreEntities context) 
{ 
    var artists = new List<Artist> 
    { 
     new Artist { Name = "Aaron Copland & London Symphony Orchestra" }, 
     etcetc 
    } 
    new List<Album> 
    { 
     new Album { Title = "ABC", Artist= artists.Single(g => g.Name == "Test")} 
    } 
} 
+0

デバッグ - リターン・ビュー(アルバム)のステートメントで停止。アルバムはどのように見えますか?それはアーティストとジャンルの価値がありますか? – BonyT

+0

はい、ありますが、値はデータベースを表すと思われるクラスからフェッチされます。 – user777310

+0

もっとコードを投稿する必要があります。投稿した内容に何も問題はなく、デバッグ時にalbums.Artist.Nameがポップアップされている場合は、エラーを報告しないでください。アルバムクラスはどのように見えますか?アルバムはどうですか? – BonyT

答えて

2

アルバムクラスのアーティストとジャンルの宣言に仮想キーワードを追加することで、うまくいきました。しかし、私はまだ何が起こっているか分かりませんし、誰かに光を当てたいと思ってもらいたいと思います。

上記を参照してください。

+0

アーティストとジャンルを怠惰に読み込んでいます。もう1回SQL Serverに戻ってくるので、実際にここで3つのリクエストをしています。 ORMがプロパティにフックしてそれらを遅延させることを可能にするためにvirtualが必要です。これらのプロパティの動的なプロキシを作成します。 –

2

ArtistまたはNamenullです。 ModelのプロパティArtistArtistインスタンスのNameためArtistの初期化インスタンスへの参照、または同様のシナリオを持っていないと言うことである

。あなたは、常に前のオブジェクトにアクセスしようとするnull値をチェックする必要があります

if (Model.Artist != null) 
{ 
    //do something with artist 
} 

すぎ、などGenreのような他の特性、放置するのと同じ説明を。

不思議なことは、しかし、Singleの使用が唯一の個々の実体が無いArtist満たすクエリ(または、そのような満たす複数の)場合に例外をスローするべきで取得することである - これはあなたの正確なコード、またはテストでありますあなたが実際に存在するArtistが存在するのでしょうか?

+0

Nameプロパティがnullの場合、このエラーは発生しません。インスタンス化されたオブジェクトのNameプロパティにアクセスするか、nullのNameを操作しようとするとこのエラーが発生します。 – Digbyswift

+0

@Digbyswift: '

  • アーティスト:<%= Model.Artist.Name%>
  • ' < - それは 'Name'にアクセスしようとしているようです。この場合、ASP.NETのインラインスクリプトで 'null'値が問題になるかどうかは完全にはわかりませんが、デフォルトではそのようなオブジェクトに対して' ToString'を呼び出す可能性もあります。 –

    +0

    データベースを表すと思われるモックアップクラスファイルのSingleを使用するコードの部分です。 var artist = new List {}のリスト宣言があり、次に新しいリスト {Title = "Copland Celebration、Vol。I"、Artist = artists.Single(a => a。名前==「アーロン・コープランド&ロンドン交響楽団」)}があり 、私はその直接の文字列に割り当てられている場合だけで罰金タイトルにアクセスすることができます。 – user777310

    3

    あなたは正しいです。このエラーは、GenreオブジェクトとArtistオブジェクトがインスタンス化されていないため、いずれかのNameプロパティにアクセスしようとするとエラーがスローされているということです。

    問題はFind()メソッド内で発生しています。 LinqToSql、EF、NHibernateまたはsimliarを使用している場合は、マッピングが正しいことを確認してください。

    更新:あなたはartists.Single(g => g.Name == "Test")を行っている場合、名前「テスト」または何でもとはアーティストが存在しない場合は改訂コードに基づいて

    、この意志はNullReferenceExceptionをスローしていました。

    私は、文字列以外でマッチを行うことをお勧めします。可能であれば、一致を実行するためにIDを使用します。これにより、より信頼性の高い一致条件が提供されます。

    SingleOrDefault()を使用し、nullが返されるのが理想的です。

    0

    GenreId、ARTISTIDとALBUMIDは 例nullにすることはできません。

    public int? GenreId { get; set; } 
    
    関連する問題