C# TPT-选择基类实例时如何查询适当的子类?

C# TPT-选择基类实例时如何查询适当的子类?,c#,entity-framework,c#-4.0,entity-framework-5,table-per-type,C#,Entity Framework,C# 4.0,Entity Framework 5,Table Per Type,我正在尝试确定当前使用表/类型层次结构的设计是否是执行以下操作的最佳方式: 例如,我有3个子类(经理、执行官、雇员),它们都是从我的基本人员继承的。然后,我想在网格视图中显示Person的所有实例,供最终用户选择并编辑其关联数据。但是,我的问题是如何在选择人员时查询适当的类型。对于Person类,我目前所做的工作如下所示: public class Person { Guid PersonID { get; set; } string FirstName { get;

我正在尝试确定当前使用表/类型层次结构的设计是否是执行以下操作的最佳方式:

例如,我有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
来获取关联的实体?

您可以使用关键字:

如果您有(例如)
DbSet
,您可以对其调用'OfType'。比如:

Person person = db.People.OfType<Manager>().Find(PersonID);
Person-Person=db.People.OfType().Find(PersonID);
编辑:
在TPT解决方案中,如果您在其他地方不需要PersonType鉴别器,则无需存储PersonType鉴别器。

谢谢您的回复。我忘记了“is”关键字,最初担心显式向下转换会忽略子类属性中的值。但是看一看LinqPad,我发现通过查询基类的单个ID生成的SQL包含一个到所有子类的连接,并希望为您将所有属性带到内存中。谢谢你,祝你度过愉快的一天!对的但这是假设我知道所选记录的类型为“Manager”。另外,这将返回person的一个实例,我想返回子实例。我的问题实际上涉及到确定我正在处理的“人”类型的最佳方法,以及在找到我正在处理的类型之后获取子实例的最佳方法。使用Sani的建议运行一些快速测试,看起来在我找到需要使用的类型后,我能够显式地向下转换。但是,
is
关键字没有在PersonType上运行,因此如果不需要,您仍然可以删除它。此外,在TPT设计中,您以任何方式加载“child”类型,我希望你的Person类是抽象的我想@Sani也在推荐同样的东西。加载person后的if语句可以是:
if(person是经理){Manager Manager=(Manager)person;}
Person person = db.People.OfType<Manager>().Find(PersonID);