2014-11-06 58 views
2

我决定首次使用Entity Framework 6.0。所以是的,我是新来的。 像往常一样,我已经建立了数据库,然后再我产生代码优先模式(通过Visual Studio向导),它看起来是这样的:实体框架6.0 - 删除上的奇怪行为

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) 

将删除StatusInfoes集合中的所有对象StatusInfo(子对象),所以我想,EF没有关于儿童删除信息。所以我得到的错误:

The DELETE statement conflicted with the REFERENCE constraint "FK_UpdateSetStatus_UpdateSet". The conflict occurred in database "UpdateWizard", table "dbo.StatusInfo", column 'UpdateSetId'. The statement has been terminated.

正如我前面提到的,有些时候它的工作原理。那些时候StatusInfo对象的集合没有被remove命令清除。

任何人都可以帮忙吗?

回答

2

为什么您收到此错误

The DELETE statement conflicted with the REFERENCE constraint "FK_UpdateSetStatus_UpdateSet". The conflict occurred in database "UpdateWizard", table "dbo.StatusInfo", column 'UpdateSetId'.

的原因在我看来是不是EF错误就错误从SQL Server未来关于事实,你有一个外键约束,这意味着你canot删除记录,因为其他记录依赖于它。

+1

@shadow在删除UpdateSet之前,必须删除具有给定UpdateSetId的所有StatusInfo条目。 – dckuehn 2014-11-06 20:43:37

+0

谢谢你们俩的时间。我知道它来自SQL Server,但我不明白为什么在某些情况下可以正常工作,而在其他情况下工作正常。 @dckuehn我认为这是EF的工作。我不想相信我们必须为每一个亲子关系做这件事。对我来说,问题发生在ctx.UpdateSets.Remove(dbUpdateSet)语句中。不知何故,信息就会丢失。 – shadow 2014-11-07 09:00:51

+0

对不起,我不能更有帮助。我工作的公司不相信硬删除任何数据,我们在任何需要的地方设置了'Deleted = True'布尔值,所以我不熟悉删除数据,尽管我确实使用了EF。搜索“级联删除”,它可能会让你更接近你所需要的。 – dckuehn 2014-11-07 22:49:08

1

我找到了解决方案,现在看起来很明显。我只需在父(UpdateSet对象)和子对象(StatusInfo对象)之间的外键约束上启用级联删除。阅读关于在EF4.0中修改实体的文章我在一段中写道:“在数据库和EF配置中打开或关闭级联删除”。在我的情况下,因为数据库是首先创建的,所以关闭了,所以当我创建模型(代码优先)时,它也在EF中关闭。所以我想在这种情况下,我必须手动删除所有的孩子。说实话,因为我是老派,对此我并不是很兴奋(约束级联删除),但我无法想象EF能够做到这一点。所以再次感谢你们。希望这有助于他人。