3

次のようにデータ コンテキストにアタッチして、既存のエンティティを更新しています。

    var updatedDocumentState = new AccDocumentState()
    {
        Id = accDocumentState.Id,
        IsDocumentary = accDocumentState.IsDocumentary,
        IsEditable = accDocumentState.IsEditable,
        IsRecursive = accDocumentState.IsRecursive,
        Title = accDocumentState.Title,
       Reportable = accDocumentState.Reportable,

    };
        context.AccDocumentStates.Attach(updatedDocumentState);
        context.ObjectStateManager.ChangeObjectState(updatedDocumentState, System.Data.EntityState.Modified);
        flag = context.SaveChanges() > 0;

これは機能しますが、添付されたエンティティを保存した後、更新しなかった既存のエンティティのプロパティが上書きされ、null 値が与えられます。エンティティを添付して、更新していない既存のエンティティのプロパティを保持するにはどうすればよいですか?

4

6 に答える 6

1

EF にはオブジェクト データ変更トラッカーがあります。プロキシ経由で有効になって いる Poco エントリの変更の追跡

基本的に You/find オブジェクト/Poco エンティティを最初に読み取ります。必要なプロパティのみを変更します。そして保存します。変更されたプロパティのみが更新されます。

autoDetectChnages を使用していない場合

 this.Configuration.AutoDetectChangesEnabled = false; ////<<<<<<<<< Default true

次に、保存する前に Detect Changes を呼び出します。

しかし、どちらにしても、概念はエンティティを取得するために最初に読み取ることに基づいています。必要な変更を加えて保存します。

実際の変更のみが Db に送り返されます。例えば:

  var mypoco = Context.Set<TPoco>.Find(1);
  myPoco.propertyXyz = "changed";
  // normally not required by default, But incase your are not using tracking proxies , tell ef heads Up
  // Context.Context.ChangeTracker.DetectChanges(); // uncomment when needed
  Context.SaveChanged();

実際の変更のみが DB に送信されます。

Rameez からの POST は正しいですが、エントリ全体を変更済みとして設定することが望ましい理由も、そうする理由も示していません。ドキュメントから State entry ポストをリンクするのはなぜですか?

   Context.Entry(poco).State = state;  // why do this ? or the objectContext equivalent 

これにより、すべてのフィールドが変更されたものとして扱われるため、SaveChanges でデータベースに送られるすべての値の更新セットが発生します。これは EF を使用する良い方法ではありません。

EF の変更の自動検出について知っておくことが重要です。変更の自動検出エンティティの状態と SaveChangesを参照してください。

于 2013-07-28T13:41:22.163 に答える
1

問題の回避策として、更新するフィールドだけのモデルを作成してください。これが一般的なシナリオであり、データベースへの余分な呼び出しを避けるために追加のモデルが保証されると仮定します。

新しい最小化されたモデルでは、同じテーブルを指していますが、必要なプロパティのみを使用しているため、必要に応じて機能します。もちろん、EF 側では何も変更されていませんが、既知のプロパティのみが更新されます。

これは EF が設計された方法ではないことに同意しますが、更新または削除を行うための余分な DB 呼び出しに不満を感じています。このソリューションはそれに役立ちます。

于 2013-07-28T13:52:14.117 に答える
1

msdnに従って、エンティティ オブジェクト エントリの EntityState を Modified に変更すると、現在の値または元の値に関係なく、オブジェクトのすべてのプロパティが変更済みとしてマークされます。 http://msdn.microsoft.com/en-us/library/system.data.objects.objectstatemanager.changeobjectstate.aspx

したがって、作成するオブジェクトには他のプロパティがnullまたはデフォルト値として含まれるため、他のすべてのプロパティがnullに設定されると思います。以下は、変更されたコードです。

 var updatedDocumentState = context.AccDocumentStates.First(a => a.Id== accDocumentState.Id);
            updatedDocumentState.IsDocumentary = accDocumentState.IsDocumentary,
            updatedDocumentState.IsEditable = accDocumentState.IsEditable,
            updatedDocumentState.IsRecursive = accDocumentState.IsRecursive,
            updatedDocumentState.Title = accDocumentState.Title,
            updatedDocumentState.Reportable = accDocumentState.Reportable,
            flag = context.SaveChanges() > 0;
于 2013-07-28T09:46:49.693 に答える
0

これを試して。必要に応じて機能するかもしれません:

var updatedDocumentState = context.AccDocumentStates.Find(accDocumentState.Id)
{
    IsDocumentary = accDocumentState.IsDocumentary,
    IsEditable = accDocumentState.IsEditable,
    IsRecursive = accDocumentState.IsRecursive,
    Title = accDocumentState.Title,
    Reportable = accDocumentState.Reportable,
};

flag = context.SaveChanges() > 0;
于 2013-07-30T05:50:28.053 に答える
0

1 つまたは 2 つのプロパティを除外するだけの場合、たとえば Title プロパティの更新を許可したくない場合は (この例では)、オブジェクトの状態を変更済みに設定した後、ターゲット プロパティで IsModified の設定を解除するだけです。

context.AccDocumentStates.Attach(updatedDocumentState);
context.ObjectStateManager.ChangeObjectState(updatedDocumentState, System.Data.EntityState.Modified);
context.Entry(updatedDocumentState).Property("Title").IsModified = false;
flag = context.SaveChanges() > 0;

また、FYI - VS の既定の MVC5 プロジェクトでは、この行を使用してオブジェクトの変更されたプロパティを設定します。

context.Entry(updatedDocumentState).State = System.Data.EntityState.Modified;
于 2014-10-27T21:13:41.067 に答える