我正在开发一个带有服务器和客户端的分布式应用程序,其中服务器通过WCF公开服务。服务器使用Entity Framework,其各种方法返回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
约束为空,另一个具有CASCADE DELETE
。上面的代码抛出了一个例外:
操作失败:关系 无法更改,因为一个或 更多的外键属性是 非空的。当进行更改时 关系,相关 foreign-key属性设置为null 值。如果外键没有 支持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,虽然在我看来这不是特定情况下的问题。