我正在使用具有服务器和客户端的分布式应用程序,其中服务器通过WCF公开服务。服务器使用实体框架,其各种方法返回EntityObjects。

在客户端中,我没有对服务器的引用。因此,在客户端中,类是完全生成的代理。

我在服务器中有一个删除方法。当我将一个对象(返回)传递给它进行删除时,它会执行此操作(剥离异常处理等):

public void DeleteCarrier(CarrierDefinition carrier)
{
    var container = new WsaEntities();

    if (carrier.EntityState == EntityState.Detached)
    {
        container.CarrierDefinitions.Attach(carrier);
    }
    container.CarrierDefinitions.DeleteObject(carrier);

    container.SaveChanges();
}


另外两个表具有CarrierDefinition的外键。其中一个FK可以为ON CASCADE SET NULL约束而为空,另一个FK具有CASCADE DELETE。上面的代码使我异常:


  操作失败:关系
  无法更改,因为一个或
  更多的外键属性是
  不可为空。进行更改时
  关系,相关
  外键属性设置为null
  值。如果外键没有
  支持空值,一个新的
  关系必须定义,
  必须分配外键属性
  另一个非空值,或者
  不相关的对象必须删除。


但是,如果我删除没有以这种方式往返的实体,它将按预期工作:

public void DeleteCarrier(Guid carrierId)
{
    var container = new WsaEntities();

    var c = container.CarrierDefinitions.Where(cd => cd.Id == carrierId).First();
    container.CarrierDefinitions.DeleteObject(c);

    container.SaveChanges();
}


在这里,ON CASCADE SET NULLON CASCADE DELETE正常工作。

我已经在调试模式下检查了载体(实体)参数,但没有找到任何不妥之处。具体来说,将填充实体集合,并包含相关对象。考虑到它已经被序列化,然后反序列化为代理类,反之则看起来非常完整和正确。但是在某个地方,有些事情并不完全正确。

我知道我同样可以使用此方法签名并继续操作,甚至可以保留签名并使用carrier参数的Id属性代替carrierId参数。但是我担心这将是许多问题中的第一个,因为整个方法并不完善。

我可以尝试什么?例如,除了附加实体外,我还需要做什么?

我应该提到的是,我在这里使用的是SQL Server Compact Edition v3.5,尽管在我看来,这并不是这种特殊情况下的问题。

最佳答案

对于可能遇到同样麻烦的任何人:我通过移至self-tracking entities解决了此问题。这些是为往返而设计的,返回时更容易使用。看看这个。

关于c# - WCF往返后,EF中的FK出现问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3617923/

10-14 11:13
查看更多