2

私は最初に EF コードを使用しており、EF 4.X DbContext Fluent Generator T4 でコードを生成しているため、2 つの poco エンティティがあります ( BindingList<T>winForms でバインディングを使用するようにリストを変更しました)。

public partial class Parent
{
    public Parent()
    {
        this.Childs = new BindingList<Childs>();
    }
    int _ParentId;
    public int ParentId { get; set; }
    BindingList<Child> _Childs;
    public virtual BindingList<Child> Childs { get; set; }
}

public partial class Child
{
    int _ChildId;
    public int ChildId { get; set; }
    int _ParentId;
    public int ParentId { get; set; }
    Parent_Parent;
    public virtual Parent Parent { get; set; }
}

また、私のマッピングファイルは次のとおりです。

    public Parent_Mapping()
    {                   
        this.HasKey(t => t.ParentId);       
        this.ToTable("Parent");
        this.Property(t => t.ParentId).HasColumnName("ParentId");
    }

    public Child_Mapping()
    {                   
        this.HasKey(t => t.ChildId);        
        this.ToTable("Child");
        this.Property(t => t.ChildId).HasColumnName("ChildId");
        this.Property(t => t.ParentId).HasColumnName("ParentId").IsRequired();
        this.HasRequired(t => t.Parent)
            .WithMany(t => t.Childs)
            .HasForeignKey(t=>t.ParentId)
            .WillCascadeOnDelete(true);
    }

私のDbContextには、これらのコードがあります:

public partial class MyContext : DBContext
{ 
    static MyContext()
    { 
       Database.SetInitializer<MyContext>(null);
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
        modelBuilder.Configurations.Add(new Parent_Mapping());
        modelBuilder.Configurations.Add(new Child_Mapping());
    }
    public DbSet<Parent> Parents { get; set; }
    public DbSet<Child> Childs { get; set; }
}

そのため、カスケード削除を有効にした1対多の関係があります。

しかし、親エンティティを削除したい場合、次のエラーが発生しました:

{
 "Cannot insert the value NULL into column 'ParentId', table 'MyDB.dbo.Child';
  column does not allow nulls. UPDATE fails.\r\nThe statement has been terminated."
}

監視にEFプロファイラーを使用したとき、EFが子テーブルを更新してParentIdをNullに設定し、代わりに親エンティティを削除しようとしていることがわかりました!:

update [dbo].[Child]
set    
   [ParentId] = null,
where  ([ChildId] = 2 /* @1 */)

私の間違いはどこですか?

4

1 に答える 1

0

私見の理由は、親と一緒に子をロードしているためです。そのような場合、子も削除する必要があります。親EFのみを削除すると、関係がnullに設定されます。EF はカスケード削除を行いません。カスケード削除は、データベースでのみ使用され、子がロードされていない場合にのみ使用されます。子をロードした場合、その更新は親エンティティの削除前に実行され、この例外が発生します。

読み込まれたエンティティに対してもカスケード削除と同様の動作をさせたい場合は、識別関係と呼ばれるものを使用する必要があります(子エンティティには、その ID と親 ID から構成される主キーがあります)。

于 2013-02-06T08:42:59.933 に答える