【发布时间】:2013-03-29 14:41:41
【问题描述】:
我发现以下有关在 .NET 4.0 下运行的 EF5 的问题,采用 Model First 方法: 我有以下自动生成的实体:
Partial Public Class Notice
Private _id As Integer
Public Property id As Integer
Get
Return _id
End Get
Friend Set(ByVal value As Integer)
_id = value
End Set
End Property
Public Property order_id As Integer
Public Property employee_id As Integer
Public Property sysdate As Datetime
Public Property content As String
Public Overridable Property order As Order
Public Overridable Property employee As Employee
End Class
Notice 实体与 Order 实体和 Employee 实体通过 1 (Order, Employee) 对多 (Notice) 的关系关联。
之后,Order 实体也与 Employee 实体有关联:many (Order) to 1 (Employee) 关系。
然后,我预计以下单元测试会失败,因为 Notice 实体关系与 Employee 实体违规(我没有分配 notice1.employee 导航属性):
<TestMethod()>
<ExpectedException(GetType(DbUpdateException))>
Public Sub ShouldNotAllowSaveNoticeWithoutAssignedEmployee()
Dim notice1 = CreateNewNotice() ' returned entity has not set any relation
notice1.order= CreateNewOrderWithAllRequiredAndRelatedEntities()
DbContext.noticeSet.Add(notice1)
DbContext.SaveChanges()
End Sub
但结果测试通过了。在数据库中,Notice->employee_id 值等于 Order->employee_id 值,这是意料之外的,因为这些外键可能指向不同的 Employee 对象。我希望我必须自己设置 notice1.employee 导航属性,如果我忘记设置,我想得到DbUpdateException 异常。
这种奇怪的 EF5 行为的原因是什么?
更新:
CreateNewNotice() 和 CreateNewOrderWithAllRequiredAndRelatedEntities() 实现:
Protected Function CreateNewNotice(Optional ByVal suffix As Int32 = 1) As Notice
Dim notice1 = New Notice() With {
.sysdate = DateTime.Now,
.content = Description & suffix ' Description is constant, for testing purposes
}
Return notice1
End Function
Protected Function CreateNewOrderWithAllRequiredAndRelatedEntities(Optional ByVal suffix As Int32 = 1) As Order
Dim order1 = CreateNewOrder(suffix) ' returned entity has not set any relation
order1.employee = CreateNewEmployee(suffix)
order1.customer = CreateNewCustomerWithAllRequiredRelatedEntities(suffix)
order1.seller = CreateNewSeller(suffix)
For i As Integer = 1 To 3
order1.notices.Add(CreateNewNotice(i)) ' created notices have not initialized relations
Next
Return order1
End Function
【问题讨论】:
-
贴出
CreateNewNotice()和CreateNewOrderWithAllRequiredAndRelatedEntities()的实现 -
我已经发布了这些实现。对我来说也很奇怪的是,在
CreateNewOrderWithAllRequiredAndRelatedEntities()方法中创建了三个没有设置关系的通知实体,但是这些通知保存在数据库中,并设置了外键。 -
如果不访问所有代码,很难说发生了什么。一个建议是为每个测试创建一个 DB 上下文对象,并在需要时将其传递给您的辅助函数(即以程序方式编写代码,而不是以面向对象的方式编写代码,这对于单元测试方法来说很好)
-
测试类中有DbContext受保护的属性,在
<TestInitialize()>属性方法中为每个测试重新实例化,然后在<TestCleanup()>属性方法中处理。
标签: vb.net entity-framework entity-framework-5 model-associations ef-model-first