c# – 更新查询需要删除并重新插入所有相关项,这会降低我的应用
我有如下数据库结构:
当我更新订单时,我使用以下查询: using (var xaction = new TransactionScope()) { foreach (OrderItemDetail orderItemDetail in OrderItemDetailClient.GetAllOrderItemDetails()) { if (orderItemDetail.OrderId == NewOrder.OrderId) { OrderItemDetailClient.DeleteOrderItemDetail(orderItemDetail); } } IEnumerable<Dispatch> dispatches = DispatchClient.GetAllDispatches().Where(x => x.OrderId == NewOrder.OrderId); foreach (Dispatch dispatch in dispatches) { foreach (DispatchItemDetail dispatchItemDetail in DispatchItemDetailClient.GetAllDispatchItemDetails().Where(x => x.InvoiceId == dispatch.InvoiceId)) { DispatchItemDetailClient.DeleteDispatchItemDetail(dispatchItemDetail); } DispatchClient.DeleteDispatch(dispatch); } OrderClient.UpdateOrder(NewOrder); xaction.Complete(); TransactionSucceded = true; } 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; } } 删除相关实体时,出现错误:无法更改关系,因为一个或多个外键属性不可为空 我知道手动我不需要在保存订单之前删除orderItemDetails,Dispatches和DispatchItemDetails.但如果我不这样做,那么我会得到下面提到的错误: Multiplicity constraint violated 我真的对实体框架不熟悉.任何人都可以建议我保存订单的好方法吗?这样我才能获得速度. 更新:
NewOrder是Order类型的属性,它在ViewModel的构造函数中初始化.以及编辑或保存时.我的意思是如果用户正在创建新订单而不是NewOrder是新订单.如果用户正在编辑现有订单,则NewOrder是现有订单.
OrderItemDetailClient是IOrderItemDetailService类型的变量,它也在ViewModel的构造函数中初始化,如下所示: OrderItemDetailClient = serviceFactory.CreateClient<IOrderItemDetailService>(); 其中暗示IOrderItemDetailService是WCF服务实现类. 同样的, DispatchClient是IDispatchService类型的变量,如下所示: DispatchClient = serviceFactory.CreateClient<IDispatchService>(); 其中暗示IDispatchService是WCF服务实现类.
对不起,该代码不是必需的.我想我忘了删除它.
更新订单自动保存Order,OrderItemDetail,Dispatch及其相关的DispatchItemDetail. 因此,如果我不删除NewOrder的现有Dispatches,那么当我更新Order时,Cascade更新或其他东西认为我已经有一个带有主键的Dispatch,我现在正试图存储.所以,我收到一个错误: Multiplicity constraint violated. The role '…' of the relationship '…' has multiplicity 1 or 0..1
我想我在上面的回答中回答了这个问题,如果我这样做,我在保存更新时会遇到违反Multiplicity约束的错误. 解决方法
问题的很大一部分似乎很可能是您可能从WCF服务中提取大量数据,可能远远超出您的需求.这很昂贵,因为您需要从数据库中提取记录,然后将它们序列化,以便将它们从WCF服务中传出(然后在WCF客户端上对它们进行反序列化).
如果您向WCF服务添加了一些方法以仅返回与特定ID相关的数据,那么您可以将返回的数据限制为仅与您尝试执行的操作相关的数据,这会加快速度.例如,而不是 DispatchClient.GetAllDispatches().Where(x => x.OrderId == NewOrder.OrderId); 您可以创建一个名为“GetDispatchesForOrderId”的服务方法,该方法接受订单ID并仅返回与其相关的调度.这将仅发回您需要的数据并且更便宜(即更快).所以上面的行将被替换为 DispatchClient.GetDispatchesForOrderId(NewOrder.OrderId) 权衡是你必须写几个服务方法. 如果您还添加了方法“OrderItemDetailClient.GetOrderItemDetailsForOrderId”和“DispatchItemDetailClient.GetDispatchItemDetailsForInvoiceId”,那么您的更新代码将变为如下所示: foreach (OrderItemDetail orderItemDetail in OrderItemDetailClient.GetOrderItemDetailsForOrderId(NewOrder.OrderId)) { OrderItemDetailClient.DeleteOrderItemDetail(orderItemDetail); } foreach (Dispatch dispatch in DispatchClient.GetDispatchesForOrderId(NewOrder.OrderId)) { foreach (DispatchItemDetail dispatchItemDetail in DispatchItemDetailClient.GetDispatchItemDetailsForInvoiceId(dispatch.InvoiceId)) { DispatchItemDetailClient.DeleteDispatchItemDetail(dispatchItemDetail); } DispatchClient.DeleteDispatch(dispatch); } OrderClient.UpdateOrder(NewOrder); 如果你不做这样的事情,那么随着数据库的增长,你的问题会随着时间的推移而变得越来越糟 – 每当你要提取的数据量超过你需要的数量时,随着不必要数据的大小增加,所以浪费的时间用于提取您实际不需要的数据. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |