2017-02-10 11 views
1

を作成し、LINQ遅延ロードと私はいくつかのクラスを持っている新しいオブジェクト

public class Album 
{ 
    public int AlbumId { get; set; } 
    public string Title { get; set; } 
    public Genre genre { get; set; } 
    public virtual Artist artist { get; set; } 
} 

public class Artist 
{ 
    public int ArtistId { get; set; } 
    public string Name { get; set; } 
    public virtual ICollection<Album> albums { get; set; } 
} 

public class ArtistResponse 
{ 
    public int ArtistId { get; set; } 
    public string Name { get; set; } 
} 

public class AlbumResponse 
{ 
    public int AlbumId { get; set; } 
    public string Title { get; set; } 
    public Genre genre { get; set; } 
    public ArtistResponse artist { get; set; } 
} 

私はアーティストですべてのアルバムをダウンロードし、AlbumResponseでそれを返すようにしようとしています。 私は、だから私はよる「アーティスト」「を含めるを()」を含め、その後、私は新しいArtistResponseを作成する新しいAlbumResponseを作成していLINQ式に

return ctx.Albums.Include(i => i.artist).Select(i => new AlbumResponse 
      { 
       AlbumId = i.AlbumId, 
       artist = new ArtistResponse { Name=i.artist.Name, ArtistId=i.artist.ArtistId}, 
       genre = i.genre, 
       Title = i.Title 
      }).ToList(); 

を持っています。不幸にもそれはうまくいかない。 InvalidOperationExceptionがスローされます。 "i.artist.ArtistId"はnullですが、ArtistIdの初期化を行わなくても "Name = i.artist.Name"だけが完璧に動作するため、なぜか分かりません。

ArtistIdを '​​AlbumResponse'の 'アーティスト'に追加するにはどうすればよいですか? 例外: "マテリアライズされた値がnullであるため、値の型 'System.Int32'へのキャストが失敗しました。結果の型の汎用パラメータまたはクエリでnull可能型を使用する必要があります" クラスAlbumおよびArtistはDatabase、AlbumId、ArtistIdにあります。 nullは使用できません。 ArtistResponseとAlbumResponseは「*レスポンス」にARTISTIDとALBUMIDので、データベースからの情報を追加したり、取得するためだけの「余分な」クラスですartistナビゲーションプロパティのArtistId列がNullable<int>とのタイプである場合は、単に

答えて

3

をint型ています

return ctx.Albums.Include(i => i.artist).Select(i => new AlbumResponse 
{ 
    AlbumId = i.AlbumId, 
    artist = new ArtistResponse { Name = (i.artist != null) ? i.artist.Name : string.Empty, ArtistId = (i.artist != null && i.artist.ArtistId.HasValue) ? artist.ArtistId.Value : 0 }, 
    genre = i.genre, 
    Title = i.Title 
}).ToList(); 

これは明らかにあなたがあなたのタイプの定義も、あなたが取得している実際のエラーメッセージを投稿しhavent'tので、ただの推測です:ArtistResponseタイプのArtistIdプロパティは、値が返さあっているかどうかを確認する必要がありますintです。

編集:

あなたはNullable<int>int?)にArtistResponseタイプのArtistIdプロパティの種類を変更した場合どのような:

public class ArtistResponse 
{ 
    public Nullable<int> ArtistId { get; set; } 
    public string Name { get; set; } 
} 
+0

これは動作しません。 "HasValue"、 "intにhasValue ...の定義が含まれていません"というエラーが表示されます。 – Pawel

+0

ArtistResponseクラスのArtistIdプロパティを自分の編集ごとにnullにするようにしてください。 – mm8

+0

それは今働いています:)しかし、私は本当に理由を理解していません。あなたはそれを説明できますか? – Pawel

1
return ctx.Albums.Include(i => i.artist).Select(i => new AlbumResponse 
      { 
       AlbumId = i.AlbumId, 
       artist = new ArtistResponse { Name=i.artist.Name, ArtistId=i.artist.ArtistId ?? 0(or Guid.NewGuid() << or this if you decide to use guid type)}, 
       genre = i.genre, 
       Title = i.Title 
      }).ToList(); 

あなたは一意の番号を割り当てる必要があります/ 0にデフォルト設定したくない場合は、アーティストIDのキーです。新しいguidおそらく?一意のint idを作成する方法を見つける必要があります。

1

あなたは完全な知識なしで、不完全な予測をしているとは限りません。エンティティは、それが正式なオブジェクトであるまでゲートからの使用について実現されていないという点で、データに関して奇妙なものです。 EG:あなたのwhere、select、およびその他の拡張構文は、オブジェクトがまだ実現していないため、まだ動作しません。

あなたは、ような単純なものを試してみてください:

return ctx.Albums.Include(i => i.artist) 

.ToList()エルス

.Select(i => new AlbumResponse 
      { 
       AlbumId = i.AlbumId, 
       artist = new ArtistResponse { Name= i?.artist?.Name ?? String.Empty, ArtistId=i?.artist?.ArtistId ?? 0}, 
       genre = i.genre, 
       Title = i.Title 
      }).ToList(); 

それは、ナビゲーションプロパティ '芸術家だための投影が実現できない場合があります。 ToList()は、プロジェクションを迅速に実現するための貧弱な人間の方法であり、本質的に言う:「.NETこれは正当なオブジェクトコレクションとしては大丈夫です。他の拡張機能を使うこともできます。これは単なる推測ですが、私はしばらくの間、EFで作業していて、ロードイベント、数学などを行うときに「実現」していることはよく知っています。または、他の人があなたが単にナビゲーションへのヌルリファレンスを取得していて、それが爆発していると述べているかもしれません。私は疑似コードをしましたか?条件付き演算子(基本的に、親がnullの場合も吹き飛ばすことなく、チェーンを介してヌルをチェックします)、結合演算子 '??'つまり、このオブジェクトがnullの場合、デフォルトを割り当てます。

関連する問題