5

私はレコードを読み込もうとしているときにEFに苦労していて、同じトランザクションでそれらのレコードを削除しています。私が最初にエラーを与えるだろうEntityState.Deleted方法、使用していました:EntityState.Deletedは機能しませんRemove(entity)は動作しますか?

The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

をしかし、私は.Remove()を使用して、私は以下の持っているようにそれを変更した場合、すべてが順調です。

  1. 使用するのに最適な時間と差異は何ですか。削除()対削除?
  2. .Deletedメソッドを使用してこの作業を行うにはどうすればよいですか?私は私のリポジトリへのコンテキストの新しいインスタンスを作成しようとすると、別の削除するが、IEntityTrackerに関連するエラーを複数のインスタンスを追跡することはできません...私も試みた。最初の読み込み依存レコードを読み込むEFにそれを知って、それらを削除します。私も読んでみた。すべて無駄に。

ここに該当する方法があります。私はこのシナリオまでも私を務めてい.Deleted方法使用する一般的なリポジトリ持っていることに注意してください(同じレコードを削除、その後読みを。)また、子オブジェクトを削除しますが、Deletedを使用します

//Delete Allocation Need and AllocatedContainers for alloc need id 
public ActionConfirmation<int> DeleteAllocRecords(int intFacilityId, AllocNeedSourceTypes needSourceType, int intNeedSourceId) 
{ 
var context = new InventoryMgmtContext(); 
var repository = new AllocationNeedRepository(context); 

//Delete Allocation Need and hence children in Allocated Containers 
var srcType = needSourceType.ToString(); 
List<AllocationNeed> allocNeeds = repository.SearchFor(
    x => x.FacilityId == intFacilityId 
    && x.NeedSourceType == srcType 
    && x.NeedSourceId == intNeedSourceId 
).ToList(); 

//var deleteRepository = new Repository<AllocationNeed>(); <--tried separate instance of context to delete...no worky. 

foreach (AllocationNeed allocNeed in allocNeeds) 
{ 
    try 
    { 
     //NO WORK: context.Entry(allocNeed).State = System.Data.EntityState.Deleted; 
     context.AllocationNeeds.Attach(allocNeed); 
     context.AllocationNeeds.Remove(allocNeed); <-- Works 
     context.SaveChanges(); 
    } 
    catch (Exception ex) 
    { 
     return ActionConfirmation<int>.CreateFailureConfirmation(ex.Message, allocNeed.Id); 
    } 
} 

答えて

6

Removeますない。このような理由から実際にRemoveを使用してください。 本当にを使用したい場合は、Deletedを使用したい場合は、外部キーをNULLにする必要がありますが、孤児のレコードで終わることになります(これは最初の場所で行うべきではない主な理由の1つです)。

+0

私が知っている.Deletedを使用する本当の理由はありませんが、そのメソッドを使用するためにジェネリックリポジトリをすでに作成していたのですが、.Removeメソッドを使用するように変更するコードは1行です。 。ありがとう! –

+0

削除は子オブジェクトを削除しません。子オブジェクトのFKがnullの場合、nullに設定されます。必要であれば、例外がスローされます。子オブジェクトを削除する方法は、関係をCode-FirstまたはDb-Firstのいずれかで 'CascadeOnDelete'とマークすることです。 – Shoe

+0

^- >またはボトムアップを削除します。 – JoeBrockhaus

2

1.)使用するのに最適な時間と差異は何ですか?削除()と削除の違いは何ですか?

エンティティの状態を[削除済み]に設定すると、SaveChanges()はデータベースからその特定のエンティティのみを削除し、NULL以外の外部キー列を使用して参照できる他の行は考慮しません。

Remove()は、関係の一部である行を考慮に入れます。

2.).Deletedメソッドを使用してこの作業をどのように行うことができますか?

関連する行に対してON CASCADE DELETEの動作が指定されている場合、データベースは自動的にそれを処理する必要があります。これは、EFでデータベースを生成させるときのデフォルトの動作です。

+0

これはDBの最初のシナリオで、データベースに設定された削除時にカスケードを設定し、EFが.edmxファイル内でそれを選択したことを確認しました.Deletedは指定されたエンティティのみを削除し、関連する –

+0

指定されたエンティティのみが削除されると言うと、EFのメモリ内のコレクションまたはデータベースからの意味ですか?あなたが 'SaveChanges()'のときにEFが例外を投げていますか?例外がない場合、EFは親エンティティの削除を送信し、カスケードが設定されている場合、データベースはすべての子を完全に削除します。しかし、子エンティティのメモリ内のコレクションが同期していないと、私は驚くことはありません。 – JoeBrockhaus

関連する問題