2013-01-09 67 views
4

使用下面的代碼,假設我有5種不同的類型,我可能會收到變量類型。有沒有寫一個條件語句的方法,而是使用變量「type」來規定模型是什麼,在這種情況下是「CommentVote?」。或者,這是我設計數據模型的方式中的一個不足之處,這五種模型中的每一種都有「投票」模型?避免多餘的條件語句

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

目前尚不清楚你想改變什麼。你能寫出一些魔術發明的代碼(即使它不會編譯),在理想的世界中顯示你想要的,以便我們可以看到你試圖避免做的代碼的哪一方面。另外,其他類型將如何不同?代碼是完全不同的,大部分是一樣的,幾乎完全一樣,完全一樣,或者是什麼? – Servy

+0

我想你可能正在尋找一個基類來定義保存的通用功能,並在每個擴展對象'type'中重寫?也許使用Table-Per-Type模式?正如上面的評論所指出的,沒有足夠的信息來猜測你想要完成什麼...... – Matthew

+0

感謝您的評論,我添加了一些我希望工作的「魔法代碼」。 @Matthew,我想我想要像你說的那樣做一些事情,但我仍然在學習很多這些東西,所以我不完全確定你說的一切是什麼意思。 –

回答

1

假設您執行相同的操作並設置相同的數據,您可以絕對將代碼簡化爲單個語句。在這種情況下,您應該有一個包含常用操作和數據的接口以及一個基於類型實例化正確對象的對象工廠。

+0

訣竅是以ORM仍然可以執行查詢的方式處理它。 – Servy

+0

這個答案在semao幫助我確定潛在問題時回答了問題,對於那些尋找答案的人來說,通過查看Factory模式可以更好地解決問題。 –

2

正如我理解你的問題,它更多的數據庫架構相關。

如果這些投票的種類並不相同(就屬性而言),我將不會爲他們使用不同的表格。相反,請創建一個帶有「類型」列和(如您提供的示例中)CommentCom的可爲空的列的投票表。

然後,您可以使用類繼承來反映您的投票(投票基類和CommentedVote子類)。

Table Per Hierarchy Inheritance in Entity Framework

更新: 最好是不要重複同樣的propertieses中的所有類。你只需要使用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; } 
} 

this非常好的博客文章,你可以找到所有可能的approches。我正在寫的一個叫做每層次表(TPH)。

+0

值得注意的是,如果您無法修改底層數據庫中的數據,則可以在數據庫或存儲過程中創建一個視圖,將每個表的相應列一起連接到這一個邏輯表中。 – Servy

+0

我可以做任何我想要的數據模型,我可能會有一個非常糟糕的設計模型。讀那篇文章,我不太瞭解,到目前爲止我所做的一切都是先在實體框架代碼中完成的。 –

+0

@semao說我使用了TPH,首先在EF代碼中我的導航屬性會發生什麼變化?單選可以屬於評論,回覆,文檔等。我甚至需要導航屬性嗎?使用模型示例查看更新的問題。 –

0

如果您使用反射實現工廠模式,您可以這樣做,一個非常基本的示例是shown here

簡而言之,你要做的是:既然你有5種不同的類型,你可以創建5個不同的類,每個類實現一個特定的接口。然後創建工廠類以使用反射來獲取最適合您情況的類(例如,使用直接類名稱(如示例中所示)或類別上的屬性(例如here))。工廠返回該接口的一個實例,然後您只需從接口調用公開的方法爲您完成所有這些工作。

最好的部分是,如果您需要製作另一種類型,您只需添加具有該屬性/名稱的另一個類,您將在工廠中搜索該類。您的其他代碼都不需要受到影響,從而使您符合開放/關閉原則。

+0

請記住,他在這裏使用的是ORM,因此這些查詢被轉換爲訪問數據庫的SQL查詢,並且不作用於內存中的對象。因此,您所做的任何事情都必須是查詢提供者足夠聰明才能轉換爲數據庫查詢的內容。反思不(通常)屬於這一類。 – Servy

+0

但是,在這種情況下,他會將數據庫調用轉移到這些類中。我假設所需的調用會從一個類型到另一個類型非常不同。 – IronMan84

+0

不是;看看他想要的代碼。他希望執行相同的LINQ查詢,但只是在一個變量表上。理論上你可以讓每個相關的ORM類型實現一個接口,初始化一個'IQueryable ',然後對其執行靜態查詢,但我真的不知道ORM是否會支持它(我知道一些做,有些不)。 – Servy