web-dev-qa-db-ja.com

EF6.0「1つ以上の外部キープロパティがnull不可であるため、関係を変更できませんでした」

「子」行を削除しようとすると、常に例外が発生します。スニペットは次のとおりです。

_using (var context = new CompanyContext())
{
    ItemType itemType = context.ItemTypes.FirstOrDefault(i => i.Name == "ServerType");
    ItemTypeItem itemTypeItem = itemType.Items.FirstOrDefault(i => i.Name == "DatabaseServer");
    itemType.Items.Remove(itemTypeItem);
    context.SaveChanges(); <=== exception!
}
_

SaveChanges()メソッドで次の例外がスローされます。

「1つ以上の外部キープロパティがnull不可であるため、関係を変更できませんでした。関係が変更されると、関連する外部キープロパティがnull値に設定されます。外部キーがnull値をサポートしない、新しい関係を定義する、外部キープロパティに別のnull以外の値を割り当てる、または関連のないオブジェクトを削除する必要があります。

エンティティ構成

_  public class ItemTypeConfiguration : NamedEntityConfiguration<ItemType>
  {
    public ConfigurationColumn ParentIDColumn;
    public ConfigurationColumn ValidationPatternColumn;
    public ItemTypeConfiguration() : base()
    {
      ParentIDColumn = new ConfigurationColumn() { Name = "ParentID", Ordinal = base.LastOrdinalPosition + 1 };
      ValidationPatternColumn = new ConfigurationColumn() { Name = "ValidationPattern", Length = 1024, Ordinal=base.LastOrdinalPosition + 2};
      this.Property(t => t.ParentID)
        .HasColumnName(ParentIDColumn.Name)
        .HasColumnOrder(ParentIDColumn.Ordinal);
      this.HasOptional(t => t.Parent).WithMany().HasForeignKey(u => u.ParentID).WillCascadeOnDelete(false);
      this.Property(t => t.ValidationPattern)
        .HasColumnName(ValidationPatternColumn.Name)
        .HasColumnOrder(ValidationPatternColumn.Ordinal)
        .HasMaxLength(ValidationPatternColumn.Length);
    }
...


  public class ItemTypeItemConfiguration : NamedEntityConfiguration<ItemTypeItem>
  {
    public ConfigurationColumn ItemTypeIDColumn;
    public ItemTypeItemConfiguration() : base()
    {
      ItemTypeIDColumn = new ConfigurationColumn(){Name="ItemTypeID", IsRequired=true, Ordinal= base.LastOrdinalPosition+1};
      this.Property(t => t.ItemTypeID)
        .HasColumnName(ItemTypeIDColumn.Name)
        .HasColumnOrder(ItemTypeIDColumn.Ordinal);
      this.HasRequired(t => t.ItemType).WithMany(t=>t.Items).HasForeignKey(u => u.ItemTypeID).WillCascadeOnDelete(true);
    }
...
_

enter image description here

ブログを見つけましたが、「DeleteObject」メソッドがありません。

http://blog.clicdata.com/2013/07/04/the-operation-failed-the-relationship-could-not-be-changed-because-one-or-more-of-the- foreign-key-properties-is-non-nullable /

何か案は?ありがとうございました。

30
Max

ItemTypeItemを削除する必要があります。 ItemType(ItemTypeID)を参照するnull不可の外部キーがあるため、単独では存在できないため、Itemsリストから単に削除することはできません。

ItemTypeItemを削除するには、追加します

context.Entry(itemTypeItem).State = EntityState.Deleted;
50
Olav Nybø

エンティティフレームワーク6.0では、メインコンテキストセットからエンティティを削除すると機能します。たとえば、投資エンティティを削除するには、次を実行します。

context.Investments.Remove(entity);
context.SaveChanges();

これは、次のように、親/所有者からエンティティを削除しようとすることとは異なります。

bankAccount.Investments.Remove(entity);
context.SaveChanges();

これにより、上記の関係を変更できませんでした例外がスローされます。お役に立てれば。

45
Gerry Polucci

エンティティ6.0では、次の間に違いがあります。

context.Investments.Remove(entity);

そして

context.Entry(entity).State = EntityState.Deleted;

最初の使用を使用し、カスケード削除が有効な場合、EFは子コレクションの必要な削除を内部的に実行します。 2番目のオプションを使用すると、EFは必要な削除を処理しませんが、これらの子オブジェクトの再バインド/削除を処理できます。

21
Eddieke

この問題は、親テーブルを削除しようとしても子テーブルのデータが存在するために発生します。カスケード削除を使用して問題を解決します。

モデルではdbcontextクラスのCreateメソッド。

 modelBuilder.Entity<Job>()
                .HasMany<JobSportsMapping>(C => C.JobSportsMappings)
                .WithRequired(C => C.Job)
                .HasForeignKey(C => C.JobId).WillCascadeOnDelete(true);
            modelBuilder.Entity<Sport>()
                .HasMany<JobSportsMapping>(C => C.JobSportsMappings)
                  .WithRequired(C => C.Sport)
                  .HasForeignKey(C => C.SportId).WillCascadeOnDelete(true);

その後、API呼び出しで

var JobList = Context.Job                       
          .Include(x => x.JobSportsMappings)                                     .ToList();
Context.Job.RemoveRange(JobList);
Context.SaveChanges();

カスケード削除オプションは、この単純なコードを使用して、親と同様に親に関連する子テーブルを削除します。この簡単な方法で試してください。

データベース内のレコードのリストの削除に使用した範囲の削除Thanks

1
Sowmiya V