2012-12-30 124 views
0

我遇到了一個情況,答案應該是非常直接的,但它沒有我。MVC 3簡單繼承

public class Note 
{ 

    #region Properties 

    public int Id { get; set; } 
    public int ClientId { get; set; } 
    public int CandidateId { get; set; } 
    public int TypeId { get; set; } 
    public DateTime DateCreated { get; set; } 
    public string UserId { get; set; } 
    public string UserName { get; set; } 
    public string Message { get; set; } 

    #endregion 

    #region Methods 

    public void Save() 
    { 

    } 

    #endregion 

} 

public class History : Note 
{ 
} 

正如您所見,History繼承了Note。它們完全一樣,兩者之間的唯一區別是類型ID。

我從數據庫中獲取數據時

public static Note Parse(SqlDataReader dr) 
    { 
     int TypeId = Convert.ToInt32(dr["TypeId"]); 
     Note Note; 

     if (TypeId == 1) 
      Note = new Note(); 
     else 
      Note = new History(); 

     Note.Id = Convert.ToInt32(dr["Id"]); 
     Note.TypeId = TypeId; 
     if (dr["ClientId"] != DBNull.Value) Note.ClientId = Convert.ToInt32(dr["ClientId"]); 
     if (dr["CandidateId"] != DBNull.Value) Note.CandidateId = Convert.ToInt32(dr["CandidateId"]); 
     Note.DateCreated = Convert.ToDateTime(dr["DateCreated"]); 

     Note.UserId = Convert.ToString(dr["UserId"]); 
     Note.UserName = Convert.ToString(dr["UserName"]); 
     Note.Message = Convert.ToString(dr["Message"]); 

     return Note; 
    } 

然後我的MVC頁上有這樣的功能,我有這樣的:

<ol id="interview-comments">         
@foreach (Note Note in Model.Notes().OfType<Note>()) 
{ 
} 
</ol> 

<ol id="history-comments">        
@foreach (History Note in Model.Notes().OfType<History>()) 
{ 
} 
</ol> 

我的問題很簡單。這是做到這一點的正確方法嗎?

/r3plica

+0

一樣的答案說,你應該_not_做這種方式。一般來說,我發現繼承可以咬你,所以如果可能的話,我傾向於遠離它。 –

+0

@ jesus.tesh,沒有必要「遠離」繼承恕我直言,但只有在適當時才使用它。不要使用螺絲刀錘釘...;) – Lucero

+0

@Lucero - 當然,我不是聲稱不應該使用繼承。爲這項工作使用正確的工具,對吧? :) –

回答

0

如果這是整個圖片,我不會在這裏使用繼承。 你說Note和History項目有不同的TypeId:s。

然後我會做到以下幾點:

@foreach(var item in Model.Notes().Where(x => x.TypeId == Note.NoteTypeId)) 
{ 
} 

//and 

@foreach(var item in Model.Notes().Where(x => x.TypeId == Note.HistoryTypeId)) 
{ 
} 

public class Note 
{ 
    public static int HistoryTypeId = 1; 
    public static int NoteTypeId = 0; 
    /* ... the rest of the implementation */ 
} 

你也可以改變TYPEID到一個枚舉和「隱藏」了一些幻數

編輯的: 根據你也可以實現使用歷史票據作爲票據上的財產進行檢查。

public class Note 
{ 
    /* ... other properties ... */ 
    public bool IsHistoric { get { return this.TypeId != 1; } } 
} 

然後檢查會簡單的是

@foreach(var note in Model.Notes().Where(x => x.IsHistoric)) 
{ 
} 

// and 

@foreach(var note in Model.Notes().Where(x => !x.IsHistoric()) 
{ 
} 
+0

是的,我在第一部分中的linq的另一個類中有類似的東西。我會採納你的建議,並使用Enum作爲類型,因爲我不喜歡使用硬編碼標識和Enum,我可以在未來添加儘可能多的我想要的東西。仍然硬編碼,但讓我感覺更好:D – r3plica

0

我可能沒有完整的圖片在這裏,但我只會使用一個類考慮 - Note。而是擁有該類別的財產 - IsHistoric。然後根據屬性而不是類型進行檢查。

0

由於HistoryNote,您的Model.Notes().OfType<Note>()也將包含History實例 - 是故意的嗎?

您可能只想使用一個實體並添加一個標誌,以判斷is是否爲筆記;這會使它更清晰並避免繼承問題。

或者你可以使用一個通用接口或抽象基類,而不是從另一個繼承一個類,而是從同一個基類繼承,這也將修復OfType問題。

或者,如果繼承是真的正確,那麼像這樣過濾:Model.Notes().Where(n => n.GetType()=typeof(Note)),或只是Model.Notes().Where(n => !(n is History)) - 有很多方法可以到達羅馬。