gpt4 book ai didi

c# - 更新查询需要删除并重新插入所有相关项目,这会降低我的应用程序的速度

转载 作者:行者123 更新时间:2023-11-30 12:41:16 26 4
gpt4 key购买 nike

我的数据库结构如下:

enter image description here

更新订单时,我使用以下查询:

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

我真的是 Entity Framework 的新手。谁能建议我保存订单的好方法?这样我就可以获得速度。

更新:

Where does NewOrder come from? Is it really new?

NewOrderOrder 类型的属性,它在 ViewModel 的构造函数中初始化。以及编辑或保存时。我的意思是,如果用户正在创建一个新订单,那么 NewOrder 就是新的 Order。如果用户正在编辑现有订单,则 NewOrder 是一个 existing Order

What is OrderItemDetailClient. What is DispatchClient?

OrderItemDetailClient是一个IOrderItemDetailService类型的变量,在ViewModel的Constructor中也是这样初始化的:

OrderItemDetailClient = serviceFactory.CreateClient<IOrderItemDetailService>();

这反过来意味着 IOrderItemDetailService 是 WCF 服务实现类。

同样,

DispatchClient是一个IDispatchService类型的变量,在ViewModel的Constructor中也是这样初始化的:

DispatchClient = serviceFactory.CreateClient<IDispatchService>();

这反过来意味着 IDispatchService 是 WCF 服务实现类。

What's the role of orderItemDetailList, TotalQuantity, and TotalAmount?

抱歉,该代码不是必需的。我想我忘了删除它。

Why do you delete ( and not add) Dispatches?

更新订单自动保存Order、OrderItemDetail、Dispatch及其相关的DispatchItemDetail。

所以,如果我不删除 NewOrder 的现有 Dispatches,那么当我更新订单时,Cascade 更新或其他东西认为我已经有了一个带有主键的 Dispatch,我现在正在尝试存储它。所以,我得到一个错误:

Multiplicity constraint violated. The role '…' of the 
relationship '…' has multiplicity 1 or 0..1

The most pressing question is: why don't you just add the items that are new, delete the ones that are removed and leave the rest alone?

我想我在上面的回答中回答了这个问题,如果我这样做,我会在保存更新时遇到 Multiplicity constraint violated 错误。

最佳答案

问题的很大一部分似乎很可能是您可能从 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);

如果您不这样做,那么随着数据库的增长,您的问题会随着时间的推移变得越来越严重 - 每次您将提取比您需要的更多的数据,并且随着不必要数据的大小增长,您花在提取实际上不需要的数据上的时间也会浪费。

关于c# - 更新查询需要删除并重新插入所有相关项目,这会降低我的应用程序的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38021210/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com