4

モデル:は、唯一の財産全体ではなく、データベースの行を含める

public class Word 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
    public DateTime? WhenCreated { get; set; } 
    public ApplicationUser Author { get; set; } 

    [NotMapped] 
    public string AuthorName 
    { 
     get 
     { 
      if (Author != null) 
      { 
       return Author.UserName; 
      } 
      else { 
       return ""; 
      } 
     } 
    } 

    public List<Definition> Definitions { get; set; } 
} 

コントローラー:

[HttpGet] 
    public IEnumerable<Word> Get() 
    { 
     return _db.Words.Include(x=>x.Author).ToList(); 
    } 

私のコントローラは、今Wordの特性の一つである全体ApplicationUserクラスを返します。 ApplicationUserという1つのプロパティを送信したい:UserName。どうやってやるの?

AuthorNameを追加しました。これは、ApplicationUserから必要なデータのみを返します。残念ながら、私はまだこのプロパティを動作させるには.Include(x=>x.Author)する必要があります。データのシリアル化処理中にAuthorを含むことを何らかの理由で省略することはできますか(ユーザーにデータを送信するときに非表示にする)?

私は.Select()メソッドを使用できますが、必要なすべてのプロパティを入力する必要があります。将来私のモデルを変更する場合、私はこれらのすべてを更新する必要があります。これは不便で時間の無駄になります。

どうすれば解決できますか?

答えて

4

Dtoオブジェクトを作成し、値を代入してDtoを返す必要があります。以下に示すように

DTO

public class WordDto 
{ 
    public string Title { get; set; } 
    public DateTime? WhenCreated { get; set; } 
    public string AuthorName { get; set; } 
} 

は、その後、あなたの行動

[HttpGet] 
public async Task<IEnumerable<WordDto>> Get() 
{ 
    return _db.Words 
       .Include(x=>x.Author) 
       .Select(x => 
        new WordDto 
        { 
         Title = x.Title, 
         DateTime = x.WhenCreated, 
         AuthorName = x.Author?.UserName ?? string.Empty 
        } 
      ) 
       .ToListAsync(); 
} 
+0

私は 'を削除します。ToList() '、より正確な感じ、コントローラがクエリを実現するようにします。 –

+0

申し訳ありませんが、私は完全に理解していません。 Selectを使用すると、 'UserName'変数だけが返されます(私はそれが何であるか分かりませんが、' Word'クラスには存在しません)。 'Word'クラスのすべてのプロパティと' Author 'のプロパティの1つを返すようにします – Piotrek

+0

次にDtoオブジェクトを作成して代入/平滑化する必要があります – Tseng

2

にあなたはそれを試すことができます。

注:ここでIncludeを使用する必要はありません。

[HttpGet] 
    public async Task<IEnumerable<Word>> Get() 
    { 
     return _db.Words.Select(x => new 
         { 
          Word = x, 
          AuthorName = x.Author.UserName 
         } 
       ).ToList(); 
    } 
+0

残念ながら、「匿名型メンバー宣言子が無効です。匿名型メンバーは、メンバー割り当て、単純名またはメンバーアクセスで宣言する必要があります。」 – Piotrek

+0

'x.Author.Select(y => new {y .UserName}) '' Author'プロパティが 'IEnumerable'でなければ? – Brad

+0

ああ。訂正されました。 Thanks @Brad – Sampath

1

ビューモデルを作成し、AutoMapperを使用して入力します。そのようにhttps://github.com/AutoMapper/AutoMapper/wiki/Queryable-Extensions

AutoMapperとProjectTo拡張子を使用して、見て、あなたがモデルを表示するプロパティを追加した場合、彼らはそう(AutoMapperのドキュメントを参照してください適切な名前に必要な特性を持つVMを作成し、あなたのEFモデル

上に存在する場合、彼らは自動的にマッピングされます。 )の命名規則について:次に

public class WordVM 
{ 
    public string Title { get; set; } 
    public DateTime? WhenCreated { get; set; } 
    public string AuthorName { get; set; } 
} 

(それが必要なあなたはVMを変更した場合、後でそれはそれを扱うことになるので、含まれるのでしょう投影するAutoMapperを使用)

_db.Words.ProjectTo<WordVM>().ToList(); 

あなたはNotMappedプロパティAutoMapperはAuthorName

0

をナビゲーションプロパティAuthorと著者プロパティNameをマップする私の問題を回避するには、それらをループその後、)(.INCLUDEとすべての関連エンティティを取得し、省略した必要はありません。私が戻ってほしくないプロパティ値。モデルが変更された場合にはメンテナンスが必要になりますが、驚くべきことに、応答時間に劇的に影響しませんでした。

関連する問題