1

我試圖確定,如果我目前的設計使用每種類型的層次結構是我最好的方式去關於以下內容:TPT - 當基類的實例被選中時如何查詢合適的孩子?

例如,我有3個子類(經理,行政,員工)所有從我的基地人繼承。然後,我想在網格視圖內顯示Person的所有實例,供最終用戶選擇並編輯其關聯數據。但是,我的問題與如何在選擇人員時查詢適當的類型有關。什麼我目前做的是一樣的東西爲Person類以下內容:

public class Person 
{ 
    Guid PersonID { get; set; }  
    string FirstName { get; set; } 
    string LastName { get; set; } 
    string PersonType { get; set; } 
} 

我然後設置PersonType場中的每個子類中時,他們實例化。

設置綁定和電線代表對SelectionChanged事件

BindingSource peopleBinding = new BindingSource(); 
peopleBinding.DataSource = db.People.Local.ToBindingList(); 
this.peopleGridView.DataSource = peopleBinding;  
this.peopleGridView.SelectionChanged += new EventHandler(peopleGridView_SelectionChanged); 

GridView的SelectionChanged事件

if (peopleGridView.SelectedRows.Count != 1) 
{ 
    return; 
} 

Person person = peopleBinding.Current as Person; 
if (person == null) 
{ 
    return; 
} 

switch (person.PersonType) 
{ 
    case "Employee":   
     Employee employee = db.Employees.Find(person.PersonID); 
     // Do Work With Employee 
     break; 
    case "Manager": 
     Manager manager = db.Managers.Find(person.PersonID); 
     // Do Work With Manager 
     break; 
    case "Executive": 
     Executive executive = db.Executives.Find(person.PersonID); 
     // Do Work With Executive 
     break; 
    default: 
     throw new ArgumentException (string.Format("Invalid type of person encountered ({0})", person.PersonType); 
} 

有沒有更好的辦法讓子類的實例,而不是使用PersonType字段作爲某種鑑別器在確定什麼DbSet我需要查詢以獲取關聯的實體?

回答

2

可以使用is關鍵字:

if (person is Employee) 
    ... 
else if (person is Manager) 
    ... 
else if (person is Executive) 
    ... 
+1

謝謝您的回覆。我忘記了關於「is」的關鍵字,並且原本害怕顯式地down-casting會忽略子類屬性的值。但看看LinqPad,我發現通過查詢基類的單個ID生成的SQL包含對所有子類的參與,並將所有屬性都帶入內存。謝謝你,祝你有美好的一天! –

0

如果你(例如)DbSet<Person>你可以直接調用`OfType <>就可以了。

Person person = db.People.OfType<Manager>().Find(PersonID); 

編輯:喜歡的東西 在TPT的解決方案,這也將消除需要存儲的PersonType鑑別假設你不需要它在其他地方。

+0

正確;但假設我知道所選記錄的類型是「經理」。此外,這將返回一個人的實例,我想返回該子實例。我的問題與確定我正在處理的「人員」類型的最佳方法有關,然後在找出我正在處理的類型後獲取子實例的最佳方法。使用Sani的建議進行一些快速測試,看起來我能夠在找到需要處理的類型後明確地向下轉發。 –

+0

'is'關鍵字雖然不在您的PersonType上運行,所以如果不需要,仍然可以放棄。 – Matthew

+1

另外 - 在TPT設計中,您是以任何方式加載「孩子」類型,我希望您的Person類是抽象的? - 我認爲@Sani推薦了同樣的東西。加載人後你的if語句可以是:'if(person is Manager){Manager manager =(Manager)person; }' – Matthew

相關問題