4

次のコードを使用して、変数の型で受け取る可能性のある 5 つの異なる型があると仮定します。5 つの条件ステートメントを記述する代わりに、1 つ記述し、変数「タイプ」を使用して、モデルが何であるか (この場合は「CommentVote」) を指示する方法はありますか? それとも、「投票」モデルを持つこれら5つのもののそれぞれでデータモデルを設計した方法の欠陥ですか?

 if (type == "comment")
 {
      CommentVote voteObj = db.CommentVotes
           .Where(x => x.UserID == UserID && x.CommentID == id)
           .SingleOrDefault();
      if (voteObj != null)
      {
          voteObj.Vote = vote;
          db.SaveChanges();
      }
      else
      {
          CommentVote c = new CommentVote { 
               CommentID = id, UserID = UserID, Vote = vote, DateCreated = DateTime.Now 
          };
          db.CommentVotes.Add(c);
          db.SaveChanges();
      }

      count = (db.CommentVotes.Count(x => x.CommentID == id && x.Vote == true) - db.CommentVotes.Count(x => x.CommentID == id && x.Vote == false));
 }

マジック コード:できるようになりたいと思っていること。

 var modelName = "";
 var modelOtherName = "";
 if (type == "comment") {
      modelName = CommentVote;
      modelOtherName = CommentVotes;
 }

      modelName voteObj = db.modelOtherName
           .Where(x => x.UserID == UserID && x.CommentID == id)
           .SingleOrDefault();

更新:以下で参照されているいくつかの読書に基づいて、私のモデルががらくたである可能性があると考え始めています。ですので、参考程度に載せておきます。それが私が解決しようとしている問題かどうか教えてください。

 public class CommentVote
 {
    public int CommentVoteID { get; set; }
    public bool Vote { get; set; }
    public DateTime DateCreated { get; set; }
    public int UserID { get; set; }
    public virtual User User { get; set; } 

    public int CommentID { get; set; }  //This row changes from model to model
    public virtual Comment Comment { get; set; }  //This row changes from model to model
 }

私はほとんど同じモデルをいくつか持っています。

4

3 に答える 3

2

あなたの質問を理解しているように、それはデータベースアーキテクチャに関連しています。

これらの種類の投票が (プロパティに関して) 互いにあまり変わらない場合、私はそれらに異なるテーブルを使用しません。代わりに、Type 列と (指定した例のように) CommentID の null 許容列を持つ 1 つの Vote テーブルを作成します。

次に、クラス継承を使用して投票を反映できます (Vote 基本クラスと CommentedVote 子クラス)。

Entity Framework の階層ごとのテーブルの継承

更新: すべてのクラスで同じプロパティを繰り返さないことが最善です。次のように inharitence を使用するだけです。

 public abstract class Vote
 {
    public int VoteID { get; set; }
    public bool isVote { get; set; }
    public DateTime DateCreated { get; set; }
    public int UserID { get; set; }
    public virtual User User { get; set; } 

    public int VoteType { get; set;} //this property specifies type of vote (e.g. VoteType=1 for CommentedVote )
 } 
 public class CommentVote : Vote
 {
    public int CommentID { get; set; }  
    public virtual Comment Comment { get; set; }  
 }
 public class OtherVote : Vote
 {
    public int OtherID { get; set; }  
    public virtual Other Other { get; set; }  
 }

この非常に優れたブログ投稿では考えられるすべてのアプローチを見つけることができます。私が書いているのは、Table per Hierarchy (TPH) と呼ばれるものです。

于 2013-01-09T18:47:23.823 に答える
1

同じアクションを実行し、同じデータを設定すると仮定すると、コードを1つのステートメントに完全に減らすことができます。この場合、一般的なアクションとデータを含むインターフェイスと、タイプに基づいて正しいオブジェクトをインスタンス化するためのオブジェクトファクトリが必要です。

于 2013-01-09T18:50:07.980 に答える
0

リフレクションを使用してファクトリパターンを実装すると、それを行うことができます。非常に基本的な例をここに示します

簡単に言うと、これは次のとおりです。5つの異なるタイプがあるため、それぞれが特定のインターフェイスを実装する5つの異なるクラスを作成します。次に、リフレクションを使用して状況に最も適したクラスを取得するファクトリクラスを作成します(例のようにまっすぐなクラス名を使用するか、ここのようにクラスの属性を使用します)。ファクトリはそのインターフェイスのインスタンスを返します。このインスタンスは、インターフェイスから公開されたメソッドを呼び出すだけで、これらすべてを実行できます。

これの最良の部分は、別のタイプを作成する必要がある場合、ファクトリで検索する属性/名前を持つ別のクラスを追加するだけでよいということです。他のコードは影響を受ける必要がないため、オープン/クローズド原則に準拠することができます。

于 2013-01-09T18:49:09.020 に答える