我在我的 POCO 实体框架应用程序中进行了 Linq To Entities 查询,如下所示:
var orders = stateRepository.Get()
.OfType<OrderedState>()
.Where(x => x.Id == stateId)
.Include(x => x.Order);
return orders.FirstOrDefault();
这OfType
是因为 State 实体使用 Table Per Hierarchy 继承。只有OrderedState
及其子级拥有Order
可供他们使用的财产。
但是,当我运行它时,我遇到了以下错误:
无法从包含 My.NameSpace.Entities.OrderedState' 类型对象的 EntityCollection 添加、附加或删除类型为“System.Data.Entity.DynamicProxies.OrderedState_6F372135E57CB68DDA1A42541A941E1F0848887EABD8BD4833D0159C9D8B055F”的对象。”
OrderedState
这是因为 EntityFramework 对继承并共享公共属性的事实感到困惑OrderState
,这是我感兴趣的?如果我.Include(x => x.Order)
从 Linq 语句中删除,则可以避免错误,但是当我的全部目的是准确检索该值时,与此 State 相关的 Order 本身返回为 null。
编辑:随着更多的研究,我意识到一些更奇怪的事情正在发生。我的 TPH 继承层次结构是这样的:
BasicState
has many -> StatefulEntities
has a -> CreationDate
LocationState : BaseState
has a -> EntityLocation
ReceivedState : LocationState
has a -> ReceivedDate
ApprovedState : LocationState
has a -> ApprovedBy
OrderedState
has a -> Order
DispatchedState : OrderedState
has a -> DispatchNumber
因此,当我寻找它时,OrderedState
它可能是 OrderedState 或 A DispatchedState,但我感兴趣的是加载Order
属性,如果我有一个未类型化的 BaseState 对象列表,我将无法执行此操作。
我现在意识到的是,当我拥有.Include( x => x.Order)
实体框架时会忽略类型参数。当我调整我的种子数据并开始收到这种类型的错误消息时,这变得更加清晰:
无法从包含 My.NameSpace.Entities.OrderedState' 类型对象的 EntityCollection 添加、附加或删除类型为“System.Data.Entity.DynamicProxies.ReceivedState_6F372135E57CB68DDA1A42541A941E1F0848887EABD8BD4833D0159C9D8B055F”的对象。”
我对此感到惊讶,所以我想我会尝试加强类型:
var orders = stateRepository.Get()
.OfType<OrderedState>()
.Where(x => x is OrderedState && x.Id == stateId )
.Include(x => x.Order);
果然,当我不尝试包含该Order
属性时,我只得到 OrderedStates 回来。一旦我使用Include
我就会得到一个异常,因为我故意试图避免返回的类型无法返回。我正在查询的 Id 绝对是 OrderedState 的 ID——事实上,我调用的方法只接受 OrderedState 对象作为测试,看看这是否会阻止这个问题。
我的目标是从 TPH 表中检索单个类型化元素,包括只有该类型化元素才有的子属性。