我正在使用具有服务器和客户端的分布式应用程序,其中服务器通过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 NULL
和ON 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/