实体框架6.0-删除时的奇怪行为

本文关键字:框架 删除 实体 | 更新日期: 2023-09-27 18:29:32

我决定第一次使用Entity Framework 6.0。所以,是的,我是新手。和往常一样,我首先创建了数据库,然后(通过Visual Studio向导)生成代码优先模型,如下所示:

Partial Public Class DataContext
Inherits DbContext
Public Sub New()
    MyBase.New("name=DataContext")
End Sub
Shared Sub New()
    DbInterception.Add(New FullTextInterceptor())
End Sub
Public Overridable Property StatusInfoes As DbSet(Of StatusInfo)
Public Overridable Property UpdateSets As DbSet(Of UpdateSet)
Public Overridable Property Users As DbSet(Of User)
Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)
    modelBuilder.Configurations.Add(New UpdateSetFtsMap)
    modelBuilder.Entity(Of StatusInfo)() _
        .Property(Function(e) e.Information) _
        .IsUnicode(False)
    modelBuilder.Entity(Of UpdateSet)() _
        .Property(Function(e) e.Title) _
        .IsUnicode(False)
    modelBuilder.Entity(Of UpdateSet)() _
        .Property(Function(e) e.Files) _
        .IsUnicode(False)
    modelBuilder.Entity(Of UpdateSet)() _
        .HasMany(Function(e) e.StatusInfoes) _
        .WithRequired(Function(e) e.UpdateSet) _
        .WillCascadeOnDelete(False)
    modelBuilder.Entity(Of User)() _
        .Property(Function(e) e.Login) _
        .IsUnicode(False)
    modelBuilder.Entity(Of User)() _
        .Property(Function(e) e.Password) _
        .IsUnicode(False)
    modelBuilder.Entity(Of User)() _
        .Property(Function(e) e.Surname) _
        .IsUnicode(False)
    modelBuilder.Entity(Of User)() _
        .Property(Function(e) e.Name) _
        .IsUnicode(False)
    modelBuilder.Entity(Of User)() _
        .HasMany(Function(e) e.StatusInfoes) _
        .WithRequired(Function(e) e.User) _
        .WillCascadeOnDelete(False)
End Sub
Public Function GetServerDate() As DateTime
    Return Database.SqlQuery(Of DateTime)("Select GetDate()").SingleOrDefault
End Function
End Class

因此,我有一个UpdateSet对象,该对象至少有一个StatusInfo。到目前为止还不错。

奇怪的是删除。这是我的代码:

Public Function DeleteById(id As Integer) As Integer Implements IDataMapper(Of UpdateSetDataTransferObject).DeleteById
    Dim result = -1
    Using ctx As New DataContext
        Dim dbUpdateSet = (From o In ctx.UpdateSets Where o.Id = id Select o).SingleOrDefault
        If dbUpdateSet IsNot Nothing Then
            ctx.UpdateSets.Remove(dbUpdateSet)
            Try
                ctx.SaveChanges()
                result = 0
            Catch ex As DbUpdateException
            End Try
        End If
    End Using
    Return result
End Function

奇怪的是,有时它是有效的。(比如说,20个中有1个)。通过调试,我观察到在大多数情况下代码

ctx.UpdateSets.Remove(dbUpdateSet)

从StatusInfo集合中删除所有StatusInfo对象(子对象),因此我认为EF没有关于要删除的子对象的信息。所以我得到了错误:

DELETE语句与REFERENCE约束"FK_UpdateSetStatus_UpdateSet"冲突。冲突发生在数据库"UpdateWizard"、表"dbo.StatusInfo"、列"UpdateSetId"中。语句已终止。

正如我前面提到的,有时它是有效的。那些时候,remove命令没有清除StatusInfo对象的集合。

有人能帮忙吗?

实体框架6.0-删除时的奇怪行为

您收到此错误的原因

DELETE语句与REFERENCE约束"FK_UpdateSetStatus_UpdateSet"冲突。冲突发生在数据库"UpdateWizard"、表"dbo.StatusInfo"、列"UpdateSetId"中。

在我看来,这不是EF错误,而是来自sql server的错误,因为您有外键约束,这意味着您不能删除该记录,因为其他记录依赖于它。

我找到了解决方案,现在看起来很明显。我只需要对父对象(UpdateSet对象)和子对象(StatusInfo对象)之间的外键约束启用级联删除。在阅读一篇关于在EF4.0中修改实体的文章时,我偶然发现了一段话,上面写着"在数据库和EF配置中打开或关闭级联删除"。在我的案例中,因为数据库是先创建的,所以这是关闭的,所以当我创建模型(代码第一)时,EF中也关闭了。所以我想在这种情况下,我不得不手动删除所有的孩子。老实说,因为我是老派,我对此并不感到兴奋(对约束进行级联删除),但我无法想象EF会有其他方式来做到这一点。所以再次感谢大家。希望这能帮助其他人。