2009-08-29 6 views
0

Linq2Sql을 Wcf 서비스의 드라이버로 사용. .... 바닥을 갈 수 있습니다 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 테이블에 연결합니다. 그렇습니다. 위의 코어 딜러에 있습니다. 상태가 채워져 코어 딜리터의 데이터에 액세스 할 수 있습니다 .CmsItemState.Title은 적절한 상태의 타일을 보여줍니다.

지금, 여기에 일이있다 ... 당신은 WCF 서비스에서 ...

domainservice.UpdateCmsDealer(dealer); 

을 줄을 주석 경우는 여전히 나에게 표시 아래의 예외와 폭탄 아니라고 정말 Linq2Sql 문제지만 오히려 Linq2Sql 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 모델 코드의 snippit입니다.

[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 거의 아무것도 나타납니다 :)

나는 Wcf 직접 Linq2Sql 개체로 작업을 계속하는 것이 좋습니다. 필요한 경우 연관이없는 플랫 프록시 클래스를 만들 수 있습니다. Wcf에 와이어를 올려 놓은 다음 서버 측 업데이트를위한 데이터 소스로 사용할 수 있습니다. 그러나 이것은 분명히 많은 노력이 필요할 것입니다. 의도 한 시나리오 ... 맞습니까?

감사합니다.

+0

제안 :'UpdateDealer'에서 try/catch를 없애고 리턴 타입을'void'로 변경하십시오. 당신은 반환 값을 무시하고 예외를 무시하고 있습니다. –

답변

1

초기에 설정 한 후에 fk 값을 변경하면 오류가 발생할 가능성이 있습니다. 사용자가 처음에 값을 설정할 수있는 사용자 정의 초기화 코드가없는 것이 확실합니까?

집합을 중단시킬 수 있으며 (설정하는 곳을 벗어날 수 있음) 올바른 방향으로 사용자를 안내해야하는 예외가 발생하지 않도록 설정 될 때마다 탈퇴 할 수 있습니다.

+0

도움에 감사드립니다. 이 문제에서 깊이있는 Wcf serializer/deserializer (clinet -> server) 관계형 데이터를 Linq 개체를 보내고 싶지 않아, 나는 프록시 개체와 함께 가야만했다. –

+0

그 시나리오는 분명히 작동합니다 (또는 최소한 나는 그것에 문제가 있다는 것을 기억하지 못합니다) - 코드가 FK 값을 설정/변경하고 있다는 것을 보는 것이 흥미로울 것입니다, 그러나 만약 당신이 다른 방법으로 작업한다면 그것은 주요 것입니다 : -) –

+0

그래, 나는 결코 그것을 이해하지 못했고, 나는 다시 미래를 다시 방문 할 것이다! –

2

기본 serializer는 State를 먼저 설정하고 StateId를 설정합니다. 그런 다음 직렬화 된 StateId를 설정하려고 시도하고 예외가 발생합니다.

문제는 DataContract 특성으로 클래스를 꾸미기를 원하지 않는다는 것입니다.당신의 LinqToSqlGenerator의 특성에

이동 및 설정 직렬화 모드이이 도구가 필요한 속성에 DataMember를 속성을 추가하고 StateId이되지 않습니다 것을 볼 수 있습니다 원인이됩니다

단방향 deserialize하는 동안 State 속성이 설정되면 DataMember가 자동으로 설정되므로

관련 문제