通过Wcf序列化Linq2Sql - 错误还是误解?

时间:2009-08-29 10:36:25

标签: wcf linq-to-sql

使用Linq2Sql作为Wcf服务的驱动程序。让我们自下而上......

在底部,我们有点击Linq2Sql ...

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

我的Wcf服务使用它......

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上的数据确实显示了相应状态的磁贴。

现在,这就是......如果你注释掉这条线......

domainservice.UpdateCmsDealer(dealer);

在Wcf服务中,它仍然以下面的例外情况进行轰炸,这表明它不是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”几乎一无所获:)

我更希望继续直接在Wcf上使用Linq2Sql对象。如果需要的话,我可以创建一个没有关联的平面代理类,将它发送到Wcf,然后将其用作服务器端更新的数据源...但是这显然是很多努力预期的情况......对吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

默认序列化程序将首先设置State,它将设置StateId。之后,它将尝试设置序列化的StateId,然后抛出异常。

问题是您没有指定要使用DataContract属性修饰类。

转到LinqToSqlGenerator的属性并将序列化模式设置为单向

这将使工具将DataMember属性添加到所需的属性,您将看到StateId将不是DataMember,因为在反序列化时设置State属性时将自动设置它。

答案 1 :(得分:1)

错误可能是由于在最初设置之后更改了fk值的某些内容 - 您确定在某个可能最初设置该值的地方没有自定义初始化代码吗?

你可以断开集合(它抛出的地方),并在每次设置时跳出(如果需要,跳过异常),这应该有希望指向正确的方向。