Vis*_*hal 2 c# linq entity-framework
这个问题看起来可能与其他类似问题重复.但我建议你阅读这个问题直到最后,然后决定它是否是一些帖子的副本?????
我的数据库中有6个表,如下所示:
我已经在所有表中插入了一些记录.
现在,我正在尝试更新订单.
起初,我只是尝试按如下方式更新订单:
CurrentOrder.UpdateOrder(Order);
Run Code Online (Sandbox Code Playgroud)
OrderClient中的UpdateOrder方法如下所示:
public Order UpdateOrder(Order Order)
{
IOrderRepository OrderRepository = _DataRepositoryFactory.GetDataRepository<IOrderRepository>();
Order updatedEntity = null;
if (Order.OrderId == 0)
{
updatedEntity = OrderRepository.Add(Order);
}
else
{
updatedEntity = OrderRepository.Update(Order);
}
return updatedEntity;
}
Run Code Online (Sandbox Code Playgroud)
在OrderRepository中:
protected override Order UpdateEntity(RateDifferenceContext entityContext, Order entity)
{
return (from e in entityContext.OrderSet
where e.OrderId == entity.OrderId
select e).FirstOrDefault();
}
Run Code Online (Sandbox Code Playgroud)
然后在DataRepositoryBase类中我使用以下方法:
public T Update(T entity)
{
using (U entityContext = new U())
{
T existingEntity = UpdateEntity(entityContext, entity);
SimpleMapper.PropertyMap(entity, existingEntity);
entityContext.SaveChanges();
return existingEntity;
}
}
Run Code Online (Sandbox Code Playgroud)
此时我收到一条错误消息:
违反了多重约束.关系'...'的作用'...'具有多重性1或0..1
所以,我认为我需要删除所有相关表中特定于此顺序的记录.所以,我尝试了下面的代码:
using (var xaction = new TransactionScope())
{
foreach (OrderItemDetail orderItemDetail in OrderItemDetailClient.GetAllOrderItemDetails().Where(x => x.OrderId == NewOrder.OrderId))
{
OrderItemDetailClient.DeleteOrderItemDetail(orderItemDetail);
}
foreach (Dispatch dispatch in DispatchClient.GetAllDispatches().Where(x => x.OrderId == NewOrder.OrderId))
{
foreach (DispatchItemDetail dispatchItemDetail in DispatchItemDetailClient.GetAllDispatchItemDetails().Where(x => x.InvoiceId == dispatch.InvoiceId))
{
DispatchItemDetailClient.DeleteDispatchItemDetail(dispatchItemDetail);
}
DispatchClient.DeleteDispatch(dispatch);
}
OrderClient.UpdateOrder(NewOrder);
xaction.Complete();
}
Run Code Online (Sandbox Code Playgroud)
现在,我得到另一个错误说:
操作失败:无法更改关系,因为一个或多个外键属性不可为空.当对关系进行更改时,相关的外键属性将设置为空值.如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象.
我在最后一个代码块中的下面提到的行中得到了这个错误:
DispatchClient.DeleteDispatch(dispatch);
Run Code Online (Sandbox Code Playgroud)
你有两个不同的问题.我们没有足够的细节来为您提供具体的解决方案,但由于这些都是非常常见的EF"陷阱",我相信了解正在发生的事情是很有价值的.
第一个错误:
违反了多重约束.关系'...'的作用'...'具有多重性1或0..1
这意味着您的外键属性不匹配.在EF中,您经常会遇到在模型中以多种方式表示相同SQL关系的情况.
例如,您的Order类可能有一个OrderItemDetails集合(使用OrderItemDetail.OrderId填充).您的OrderItemDetail也可能有一个Order属性,使用相同的外键填充.如果这两个属性都标记为已更改但新值不匹配,则EF不知道要保存到OrderItemdetail.OrderId字段的新值.在那种情况下,它将抛出此异常.如果OrderItemDetail具有Order属性和OrderId属性,则会出现同样的问题.
要避免此问题,您必须非常小心修改哪些属性.使用属性映射器可能很危险,因为它们可能"意外地"修改错误的属性并导致许多类似的问题.我们需要看看SimpleMapper如何工作或如何配置映射以进行真正的故障排除.
第二个错误:
操作失败:无法更改关系,因为一个或多个外键属性不可为空.当对关系进行更改时,相关的外键属性将设置为空值.如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象.
此错误通常意味着您并未真正删除对象.您正在从关系集合中删除该对象,该集合仅将外键设置为null.
继续上面的例子,如果你调用myOrder.OrderItemDetails.Remove(detail)然后调用SaveChanges,你可能会认为它只会从数据库中删除OrderItemDetail记录,但这并不是你告诉它要做的.您已从与 myOrder 关联的订单商品详细信息列表中删除它.为了实现这一点,EF生成一个UPDATE语句,将OrderId列设置为null.如果没有关于您的模型和DeleteDispatch方法的代码的更多细节,很难确切地知道问题的位置,但异常意味着它试图将该外键属性设置为null并失败,因为它不可为空.
"修复"是直接从Context集合而不是相关项集合中删除项目.即代替myOrder.OrderItemDetails.Remove,你应该调用context.OrderItemDetails.Remove.这会删除真实的记录.