我有两个实体,它们通过 TPT 继承模式相连接:
因此,
public class User {...}
public class Employee : User {...}
如您所见,基类不是抽象的,因此两种实体类型都可以添加到数据库集中。有两个独立的集合(我需要它们都在我的模型中):
public DbSet<User> Users { get; set; }
public DbSet<Employee> Employees { get; set; }
因此,
Users
表包含所有实体,而Employees
仅包含那些被实例化为new Employee()
的对象的附加数据。
现在,当我尝试使用Find
方法从Employees
集合中获取实体时,我期望它只会返回“实际”的员工。但是,如果我指定User实体的Id,EF仍然会从数据库中获取它,然后抛出一个InvalidOperationException
异常:
“指定的从已实现类型'System.Data.Entity.DynamicProxies.User_B2E5EC989E36BE8C53B9285A70C4E879F0B5672E1D141B93FD299D1BA60258EE'到'Data.Employee'的转换无效。”
很明显不能将User强制转换为Employee。
我的问题是 - 是否有一种方法可以配置TPT继承,使得当处理不存在的Id时就像传递不存在的Id一样,Find方法只返回null。
我的当前解决方案是:
public Employee GetEmployeeById(int id)
{
try
{
return Employees.Find(id);
}
catch(InvalidOperationException ex) when (ex.Message.StartsWith("The specified cast from a materialized"))
{
return null;
}
}
但我不喜欢它的外观 - 所以也许有一个更好(更优雅)的解决方案?
DbSet
。它意味着你有一个DbSet<User>
,该集合在数据库中使用TPT层次结构进行拆分。然后,你应该使用OfType<Employee>()
仅查询Employee
。 - haim770this.Set<Employee>().Find(id);
。 - haim770