0

小さな仕事のように感じる何かをしようとしていますが、それを行う簡単な方法がわかりません。これを行うための私のアプローチはすべて、単純なタスクに対して非常に複雑になります。

私はこれらのモデルを持っています:

public class Blog
{
    public int Id { get; set; }
    public String Name { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public String Name { get; set; }
    public int BlogId { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    public int Id { get; set; }
    public String CommentText { get; set; }
    public int PostId { get; set; }
    public int UserProfileUserId { get; set; }
}

public class UserProfile
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

追加されたコメントの部分ビューで、コメントを作成したユーザーの完全なユーザー名を表示したいと考えています。ビューと部分ビューで基本クラスを使用するだけで、追加されたコメントに完全なユーザー名を除いて必要なものがすべて取得されます。これまでのところ、次の方法を考えてきました。

ViewModels - これにより、クラスごとに ViewModel が作成され、コントローラーに手動で入力/マップされます。

ビューのコード - UserProfileUserId を持っているので、ビューからリポジトリに問い合わせることができますが、これは MVC で MVC を強制終了するので、やりたくありません。

UserProfileFirstName と UserProfileLastName を Comment クラスに外部キーとして実際に追加する - これは、データベースをビュー固有のデータで満たすように感じます。リレーショナル データベースには属しません。

通常の SQL を使用してデータベースにクエリを実行する - SQL を知っているという理由だけで、これを実行する方法になる可能性があります。しかし、再びMVCでMVCを殺しています。

どうすればいいですか?私のばかげた見過ごされたオプションはどこにありますか? 私はたくさん検索しましたが、答えを見つけることができませんでしたが、これは私がまだすべての技術用語を知らないことに関連している可能性があります. これが1000回前に回答された場合は申し訳ありません。

4

1 に答える 1

2

理想的には、ドメイン モデルを変更してAuthorタイプのプロパティを含めUserProfile、JOIN (コメント テーブルとユーザー テーブル) を使用してそのデータをロードします。

public class Comment
{
    public int Id { get; set; }
    public String CommentText { get; set; }
    public int PostId { get; set; }
    public UserProfile Author { get; set; }
}

編集: コメントの質問に従って

これが私がこれを行う方法です。

私のリポジトリメソッドにはこれらのメソッドがあります

List<Comment> GetCommentsForPost(int postId);
BlogPost GetPost(int postId);

このような単一のブログ投稿を表す ViewModel があります

public class PostViewModel
{
   public int PostID { set;get;}
   public string PostText { set;get;}
   public string AuthorDisplayName { set;get;}
   public List<CommentViewModel> Comments { set;get;}

   public PostViewModel()
   {
      Comments=new List<CommentViewModel>();
   }
}
public class CommentViewModel
{
  public int CommentID {set;get;}
  public string Text { set;get;}
  public string AuthorDisplayName { set;get;}  
}

GETアクションで、リポジトリからデータを取得し、それをViewModelにマップしてビューに送信します

public ActionResult ViewPost(int id)
{

  var post=repositary.GetPost(id);
  if(post!=null)
  {
    PostViewModel vm=new PostViewModel { PostID=id };
    vm.PostText=post.Name;
    var comments=repo.GetCommentsForPost(id);
    foreach(var item in comments)
    {
      vm.Comments.Add(new CommentViewModel { CommentID=item.Id, 
                              AuthorDisplayName=item.Author.FirstName});
    }
    return View(vm);
  }
  return View("NotFound");
}

これで、ビューは強く型付けされますPostViewModel

@model PostViewModel

<h2>@Model.PostText</h2>
@Html.Partial("Comments",Model.Comments)

そして、あなたの部分ビュー(Comments.cshtml)は、コレクションに強く型付けされますCommentViewModel

@model List<CommentViewModel>
@foreach(var item in Model)
{
  <div>
     @item.Text
     <p>Written by @item.AuthorDisplayName</p>
  </div>
}

これで、ビューはドメイン モデルに直接依存しなくなりました。これにより、明日、必要に応じて別のソースからデータを取得し (例:Web サービスからコメントを取得する)、ビュー モデルにマップすることができます。

いくつかのメモ

ビューにコードを追加しすぎないでください。できるだけ純粋な HTML のままにしましょう。ビューから直接データ アクセスを呼び出す必要はありません。

理解できるように、ドメイン モデルをビューモデルに手動でマッピングしました。そのために、 Automapperなどのマッピング ライブラリを使用できます。また、GET アクション メソッドにあるコードの一部を別のサーバー層に移動して、複数の場所で再利用できるようにすることもできます。

于 2012-12-15T22:55:01.587 に答える