2009-05-12 9 views
8

LINQオブジェクトがデータベースにまだ挿入されていない(新規)か、最後の更新(ダーティ)以降に変更されているかどうかを判断する方法はありますか? WPFを使用してUIをLINQオブジェクトにバインドする予定で、オブジェクトが既にデータベースに存在するかどうかに応じて異なる動作をする必要があります。私は考えることができるLINQ to SQL - 新規/ダーティーオブジェクトの追跡

MyDataContext context = new MyDataContext(); 
MyObject obj; 
if (new Random().NextDouble() > .5) 
    obj = new MyObject(); 
else 
    obj = context.MyObjects.First(); 
// How can I distinguish these two cases? 

のみシンプルソリューションは、負の値に新しいレコードの主キーを(私のPKがIDフィールドであるため、INSERT上の正の整数に設定されます)を設定することです。これは、新しいレコードを検出するためにのみ機能します。また、ID PKが必要で、新しいオブジェクトを作成するコードを制御する必要があります。

これを行うより良い方法はありますか? context.SubmitChanges()で何をすべきかを知るために、LINQがこれらのオブジェクトのステータスを内部的に追跡している必要があるようです。その "オブジェクトステータス"にアクセスする方法はありますか?

明確化 明らかに私の最初の質問は混乱していました。私はレコードを挿入または更新する方法を探していません。私は、そのオブジェクトが挿入されていない(新しい)か、最後の更新(汚い)から変更されているかどうかを判断するために、LINQオブジェクトが与えられたときに、方法を探しています。

答えて

14

ChangeSet changes = context.GetChangeSet();

changes.Inserts.Contains(yourObjectが)、それは新しく、changes.Updates.Contains(yourObject)した場合のSubmitChangesが

呼び出されたときに挿入される場合、それはデータベースにすでにだし、上の更新されますでSubmitChanges()

1

DataContextオブジェクトは、データの変更を内部的に追跡し、SubmitChanges()を呼び出すときに生成されるSQLクエリを最適化できるようにします。あなたがでSubmitChanges()を呼び出したときに今、それはINSERTとの両方を生成します

MyDataContext context = new MyDataContext(); 
MyObject obj; 
if (new Random().NextDouble() > .5) 
{ 
    obj = new MyObject(); 
    context.MyObjects.InsertAllOnSubmit(obj); 
} 
else 
    obj = context.MyObjects.First(); 

:データベースに新しいオブジェクトを挿入するのではなく、既存のオブジェクトを更新する場合

、あなたのような何かを行う必要があります必要に応じて更新してください。新しいオブジェクトにプライマリキーが必要な速さに応じて、すぐにオブジェクトを送信し、変更の追跡をフラッシュして新しいプライマリキーを取得することができます。

+1

これは私が探しているものではありません。私はLINQを使用して挿入/更新する方法を知っています。私が必要とするのは、任意のLINQオブジェクトの状態を判断することです。 –

2

私はLINQは、(データオブジェクト)を作成し、主キー場合は、各オブジェクトはのIDataObjectインターフェイスに各データオブジェクトで

/// <summary> 
/// This interface is used to implement IsNew in all LINQ objects so a Generic Save method 
/// can be used. 
/// </summary> 
public interface IDataObject 
{ 

    #region Properties 


     #region IsNew 
     /// <summary> 
     /// Is this a new object 
     /// </summary> 
     bool IsNew 
     { 
      get; 
     } 
     #endregion 


    #endregion 

} 
#endregion 

を実装している私がtrueを返すためにIsNewプロパティを実装する各オブジェクトの部分クラスを作成します設定されています)

/// <summary> 
/// Is this a new object 
/// </summary> 
public bool IsNew 
{ 
    get 
    { 
     // initial value 
     bool isNew = (this.CustomerID > 0); 

     // return value 
     return isNew; 
    } 
} 

はその後、私のDataContextに私はのIDataObjectとして保存するojbectをキャストし、それが新しいものである場合、私は(のSubmitChangesを呼び出す前に、InsertOnSubmit()を呼び出します。

これは最も単純な方法ではないかもしれませんが、すべてのオブジェクトを一般的に保存することができます。

各テーブルがインターフェイスを実装するのに数分かかりますが、Generic Save()メソッドを呼び出すことができます。

0

INotifyPropertyChangingおよびINotifyPropertyChangedインターフェイスには、挿入時に発生する特定のメソッドがあり、オブジェクトが汚れているかどうかを知ることができます。 SQLMetalを使用すると、自動的にSQLMetalが実行されます。独自のエンティティークラスを作成する場合は、これらの配管スタッフを手動で作成してください。しかし、このソリューションがスケーラビリティの観点から適しているかどうかはわかりません。私はそれを試していない。それは、それが挿入を行うマシン上でイベントを発生させるので、問題があるようです。