如何确定具有关系属性的实体是否有更改

时间:2009-10-28 22:38:22

标签: entity-framework

Dim myEmployee as Employee = myObjectContext.Employee.Where("it.EmployeeID = 1").First()

以下行将使e.EntityState等于EntityState.Modified:

myEmployee.Name = "John"

但是,更改作为关系的属性将使e.EntityState = EntityState.Unchanged。例如:

myEmployee.Department = myObjectContext.Department.Where("it.DepartmentName = 'Accounting'").First()

如何判断myEmployee是否有变化?我需要知道,所以我可以记录对员工记录所做的更改,以便进行审计。

2 个答案:

答案 0 :(得分:2)

有一种方法可以获得关系的状态,但它并不像实体的状态那样容易获得。

ObjectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState state)  返回IEnumerable<ObjectStateEntry>,包含两者,实体和关系的条目(ObjectStateEntry上有IsRelationship属性,因此您可以确定它的关系或实体)。

当你以你的方式改变关系时,我用你的例子测试了

myEmployee.Department = myObjectContext.Department.Where("it.DepartmentName = 'Accounting'").First()

我发现通过为每个可能的EntityState调用GetObjectStateEntries,添加一个ObjectStateEntry状态已添加:

myObjectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added)

现在,您可以查看状态条目的当前值,以查看它们是否与关系的结尾匹配(不太好)。但是,它有点复杂,我不确定它是否能在每种情况下满足您的需求。

答案 1 :(得分:0)

当我尝试在Entity框架中验证时,我遇到了类似的问题: 经过一番研究后我发现了一个解决方案: (见im发布整个验证解决方案)

验证界面:

Interface IValidatable

Function Validate(Optional ByVal guardando As Boolean = False) As List(Of  ApplicationException)

End Interface

处理分部类中的SavingChanges事件:

Partial Class FacturacionEntities

Private Sub FacturacionEntities_SavingChanges(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SavingChanges
    Dim objects As New List(Of System.Data.Objects.ObjectStateEntry)
    objects.AddRange(Me.ObjectStateManager.GetObjectStateEntries(EntityState.Added))
    objects.AddRange(Me.ObjectStateManager.GetObjectStateEntries(EntityState.Modified))

    Dim errors As New List(Of ApplicationException)
    For Each obj In objects
        If obj.IsRelationship Then
            Dim fro = DirectCast(obj.CurrentValues(1), EntityKey)
            Dim k As New EntityKey("FacturacionEntities." & fro.EntitySetName, fro.EntityKeyValues(0).Key, fro.EntityKeyValues(0).Value)
            errors.AddRange(DirectCast(Contexto.Facturacion.GetObjectByKey(k), IValidatable).Validate())
        Else
            errors.AddRange(DirectCast(obj.Entity, IValidatable).Validate)
        End If
    Next
    If errors.Count > 0 Then
        Dim err_list As String = ""
        For Each s In errors
            err_list = err_list & s.Message & vbCrLf
        Next
        Throw New ApplicationException(err_list)
    End If
End Sub
  End Class

请注意,“Contexto.Facturacion”是Entity框架引擎生成的Entities类的实例。