这个问题看起来像是其他类似问题的重复。但我建议您仔细阅读问题,然后再决定是否与某些帖子重复????
我的数据库中有6个表,如下所示:
我已经在所有表中插入了一些记录。
现在,我正在尝试更新订单。
首先,我只是尝试按以下方式更新订单:
CurrentOrder.UpdateOrder(Order);
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;
}
并在OrderRepository中:
protected override Order UpdateEntity(RateDifferenceContext entityContext, Order entity)
{
return (from e in entityContext.OrderSet
where e.OrderId == entity.OrderId
select e).FirstOrDefault();
}
然后在DataRepositoryBase类中,我使用以下方法:
public T Update(T entity)
{
using (U entityContext = new U())
{
T existingEntity = UpdateEntity(entityContext, entity);
SimpleMapper.PropertyMap(entity, existingEntity);
entityContext.SaveChanges();
return existingEntity;
}
}
这时我出现了一个错误,说:
违反多重性约束。关系“ ...”的角色“ ...”具有多重性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();
}
现在,我收到另一个错误消息:
操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系。对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
我在最后一个代码块的以下提到的行中收到此错误:
DispatchClient.DeleteDispatch(dispatch);
参考方案
您有两个不同的问题。我们没有足够的细节来为您提供特定的修复程序,但是由于它们都是非常常见的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。这将删除真实记录。
Java中的OrderByDecending(LINQ)等效项 - java嗨,我是一名使用Java的C#开发人员。问题很简单:我如何才能将下面的c#代码写入Java并仍能正常工作:myCoffeeList.OrderByDescending(x => x.Name?.ToLower()?.Trim() == sender.Text.ToLower()?.Trim())); 我的sender.Text基本上是一个文本框。文本的…
LINQ RemoveAll代替循环 - c#我有两个for循环,用于从列表中删除项目。我正在为这些循环寻找等效的LINQ语句for (Int32 i = points.Count - 1; i >= 0; i--) { for (Int32 j = touchingRects.Count - 1; j >= 0; j--) { if (touchingRects[j].HitTest(po…
Linq Any()的哪种使用效率更高? - c#我有一个Linq查询,如下所示:return this._alarmObjectAlarmViolationList .Where(row => row.ObjectId == subId) .Where(row => row.AlarmInternalId == "WECO #1 (StdDev > UCL)") .W…
LINQ to SQL中的“无法识别的表达式节点数组索引linq”异常 - c#这是我的LINQ,其中我将DateTime类型的字段与当前日期进行了比较- var srs = (from s in dcDistrict.ScheduledReportStatus where s.ReportConfigId.Equals(ConfigId) && s.Status.HasValue && s.Status…
LINQ to XML语法 - c#我有一个简单的POCO类,用于保存从XML文件提取的数据,该XML文件定义如下:public class Demographics { public string FirstName { get; set; } public string LastName { get; set; } public string MiddleName { get; set; …