4


1

次のコードではうまくいきません

public void Foo(){CompanyDataContext db = new CompanyDataContext();クライアントclient =(db.Clients ....からcを選択)。Single();バー(クライアント) }

public void Bar(クライアントクライアント){CompanyDataContext db = new CompanyDataContext(); db.Client.Attach(クライアント); client.SomeValue = "foo"; db.SubmitChanges(); }

これはうまくいきません、私はエラーメッセージが出ます。 msgstr "" "新しいものではないエンティティをアタッチまたは追加しようとしました、おそらく別のDataContextからロードされたのでしょう。 これはサポートされていません。」

アプリケーション全体でDataContextをどのように使用して参照を渡す必要がないのですか。

6 Answer


5


彼らは本当に「これはサポートされていません」という意味です。 他のデータコンテキストから取得したオブジェクトへのアタッチは実装されていません。

この問題にはいくつかの回避策があります。推奨される方法はオブジェクトをシリアル化することですが、これは簡単ではないし、クリーンなアプローチでもありません。

私が見つけた最も簡単なアプローチは、このようなオブジェクトを取得するために読み取り専用のDataContextを使うことです:

MyDataContext dataContext = new MyDataContext(){DeferredLoadingEnabled = false、ObjectTrackingEnabled = false};

このコンテキストから取得したオブジェクトは別のコンテキストにアタッチできますが、一部のシナリオにのみ適用されます。


4


http://plinqo.com[PLINQO]フレームワークはすべてのエンティティに対してデタッチを生成し、そのエラーを受け取らずにオブジェクトのデタッチと再アタッチを容易にします。
public void Foo(){CompanyDataContext db = new CompanyDataContext();クライアントclient =(db.Clients ....からcを選択)。Single(); //ここでdetachを呼び出せるようにします。client.Detach();バー(クライアント) }

public void Bar(クライアントクライアント){CompanyDataContext db = new CompanyDataContext(); db.Client.Attach(クライアント); client.SomeValue = "foo"; db.SubmitChanges(); }

これは、デタッチがどのように実装されたかを説明する記事です。 http://www.codeproject.com/KB/linq/linq-to-sql-detach.aspx


1


うん それはそれがどのように機能するかです。

あなたはこのasp.netにタグを付けたので私はそれがウェブアプリであると思います。 リクエストごとに1つのデータコンテキストが必要ですか。

(P.S WinFormsではもっと難しいです。


0


Linq2Sqlとのすべての通信をカプセル化するデータアクセスクラスを作成しました。 これらのクラスは、それらのオブジェクトで使用する独自のデータコンテキストを持ちます。

パブリッククラスClientDataLogic {private DataContext _db = new DataContext();}

パブリッククライアントGetClient(int id){return _db.Clients.SingleOrDefault(c => c.Id == id);} }

public void SaveClient(クライアントc){if(ChangeSetOnlyIncludesClient(c))_db.SubmitChanges(); }}

もちろん、オブジェクトが必要な限り、このオブジェクトをインスタンス化したままにしておく必要があります。

rigthオブジェクトだけが変更されているかどうかをチェックするのはやや面倒ですが、次のようなメソッドを作ることができます。

void ChangeClientValue(int clientId、int value);

しかし、それは多くのコードになる可能性があります。

アタッチとデタッチはLinq2Sqlにはやや欠けている機能です、あなたがそれをたくさん使う必要があるなら、あなたはおそらくLinq2Entitiesを使うべきです。


0


オブジェクトのバージョン管理を処理する必要があります。

エンティティがバージョンメンバを宣言している場合、または更新チェックポリシーを持っていない場合にのみ、エンティティは元の状態なしで変更されたものとして添付できます。

そのため、タイムスタンプメンバや他の「バージョン管理」メカニズムが提供されていない場合、そのデータが変更されたかどうかをLINQが判断することはできません。したがって、表示されるエラーです。

私は自分のテーブルにタイムスタンプ列を追加することでこの問題を解決しましたが、それを回避する他の方法があります。 Rick Strahlはまさにこの問題についていくらかまともな articlesを書きました。

また、 thisおよびhttp://visualstudiomagazine.net/featuresも参照してください。もう少し詳しい情報は/article.aspx?editorialsid=1340[this]をご覧ください。


0


これを見てみると、元のDataContextが破棄されている限りはうまく機能するように見えます。

using()を使用してDataContextをラップし、2番目のDataContextにアタッチした後に変更が行われることを確認しますか? それは私のために働きました..

public static void CreateEntity(){ユーザuser = null; using(DataClassesDataContext dc = new DataClassesDataContext()){user =(dc.Usersのuから選択します).FirstOrDefault(); UpdateObject(ユーザー)。 }

public static void UpdateObject(ユーザーユーザー){using(DataClassesDataContext dc = new DataClassesDataContext()){dc.Users.Attach(user); user.LastName = "テストB"; dc.SubmitChanges(); }}