2009-08-29 12 views
0

Wcfサービス用のドライバとしてLinq2Sqlを操作する。 ....ボトムアップに行くことができます Linq2SqlをWcfでシリアライズ - バグや誤解?

下部にダウン、我々はLinq2Sqlを打つ方法を...持っているような私のWCFサービスによって使用されます

public virtual void UpdateCmsDealer(CmsDealer currentCmsDealer) 
{ 
    this.Context.CmsDealers.Attach(currentCmsDealer, 
      this.ChangeSet.GetOriginal(currentCmsDealer)); 
} 

...

public bool UpdateDealer(CmsDealer dealer) 
{ 
    try 
    { 
     domainservice.UpdateCmsDealer(dealer); 
     return true; 
    } 
    catch 
    { 
     return false; 
    } 
} 

そして、私のWPFのクライアントコードから呼び出されるので(下記の擬似コード)...

[...pull the coreDealer object from Wcf, it is a CmsDealer...] 
[...update the coreDealer object with new data, not touchign the relation fields...] 
try 
{ 
    contextCore.UpdateDealer(coreDealer); 
} 
catch (Exception ex) 
{ 
    [...handle the error...] 
} 

、CmsDealerタイプ>は1がありますforiegnキーの関係では、 "StateId"フィールドを使用してCmsItemStatesテーブルにリンクします。したがって、上記のcoreDealer.StateIdが満たされ、coreDealer.CmsItemState.Titleのデータにアクセスすると、適切な状態のタイルが表示されます。

さて、ここでの事はある...あなたは、WCFサービスでは...

domainservice.UpdateCmsDealer(dealer); 

を行をコメントアウトした場合、それはまだそれが私に示し、以下の例外、と爆弾ではないこと実際Linq2Sqlの問題ではなく、Linq2Sql over Wcfの問題です。

"System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException was unhandled by user code 
    Message="Operation is not valid due to the current state of the object." 

InnerExceptionがNULLです。エラーハンドラ(Catch ex bloc)にバブルアップしたときの最終結果です。例外メッセージはデシリアライザについて不平を言います。私がデバッグを奪うことができるとき、エラーを投げる実際のコードは、Linq2Sqlによって構築されたCmsDealerモデルコードからのこのスニッピです。

[Column(Storage="_StateId", DbType="UniqueIdentifier NOT NULL")] 
public System.Guid StateId 
{ 
    get 
    { 
     return this._StateId; 
    } 
    set 
    { 
     if ((this._StateId != value)) 
     { 
      if (this._CmsItemState.HasLoadedOrAssignedValue) 
      { 
       throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException(); 
      } 
      this.OnStateIdChanging(value); 
      this.SendPropertyChanging(); 
      this._StateId = value; 
      this.SendPropertyChanged("StateId"); 
      this.OnStateIdChanged(); 
     } 
    } 
} 

要するに、「カバーの下」には問題があるようですが、ドキュメントは存在しません。 "ForeignKeyReferenceAlreadyHasValueException"の地獄googleingはほとんど何も表示されません:)

私はLinq2SqlオブジェクトをWcfで直接使用して作業を続けたいと思います。私は、必要に応じて、関連がないフラットプロキシクラスを作成し、それをWcfに渡してから、サーバーサイドの更新用のデータソースとして使用することができます...しかし、これは明らかにこれが意図されたシナリオ...そうですか?

ありがとうございます!

+0

提案: 'UpdateDealer'でtry/catchを取り除き、戻り値の型を' void'に変更してください。あなたは戻り値を無視しており、例外も無視しています。 –

答えて

1

最初に設定した後にfkの値を変更するとエラーが発生する可能性があります。最初に値を設定していたカスタムの初期化コードがないのは間違いありませんか?

あなたはセットを(どこに投げているのか)打ち破り、必要な場合は例外をスキップして、正しい方向に向かうはずです。

+0

助けてくれてありがとう。この問題では、Wcfシリアライザ/デシリアライザで、リレーショナルデータを持つLinqオブジェクトを(クリケット→サーバ)送信したくないと思われる場合は、プロキシオブジェクトを使用する必要がありました。 –

+0

そのシナリオは間違いなく動作します(または、少なくとも私はそれに問題があることを覚えていません) - コードがFK値を設定/変更していたのを見て興味深いでしょうが、 - ) –

+0

ええ、私はそれを理解したことはありません、私は再び最初にそれを再訪します! –

2

デフォルトのシリアライザは最初にStateを設定し、StateIdを設定します。その後、シリアライズされたStateIdを設定しようとすると、例外がスローされます。

問題は、クラスをDataContract属性で装飾するように指定していないことです。あなたのLinqToSqlGeneratorの性質に

移動して、設定シリアライズモードにこのツールが必要とされる特性にデータメンバーの属性を追加すると、あなたはSTATEIDはならないことを確認できますが発生します

単方向デシリアライズ時にStateプロパティが設定されたときに自動的に設定されるため、DataMemberです。

関連する問題