繁体   English   中英

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

[英]Update query needs that all related items to be deleted and re-inserted, which degrades the speed of my application

我有如下数据库结构:

在此输入图像描述

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

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;
    }
}

删除相关实体时,出现错误: The relationship could not be changed because one or more of the foreign-key properties is non-nullable

我知道手动我不需要在保存订单之前删除orderItemDetails,Dispatches和DispatchItemDetails。 但如果我不这样做,那么我会得到下面提到的错误:

Multiplicity constraint violated

我真的对实体框架不熟悉。 任何人都可以建议我保存订单的好方法吗? 这样我才能获得速度。

更新:

NewOrder来自哪里? 这真的是新的吗?

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

什么是OrderItemDetailClient。 什么是DispatchClient?

OrderItemDetailClientIOrderItemDetailService类型的变量,它也在ViewModel的构造函数中初始化,如下所示:

OrderItemDetailClient = serviceFactory.CreateClient<IOrderItemDetailService>();

其中暗示IOrderItemDetailService是WCF服务实现类。

同样的,

DispatchClientIDispatchService类型的变量,它也在ViewModel的构造函数中初始化,如下所示:

DispatchClient = serviceFactory.CreateClient<IDispatchService>();

其中暗示IDispatchService是WCF服务实现类。

orderItemDetailList,TotalQuantity和TotalAmount的作用是什么?

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

为什么要删除(而不是添加)Dispatches?

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

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

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

最紧迫的问题是:为什么不添加新项目,删除已删除的项目并将其余项目单独留下?

我想我在上面的回答中回答了这个问题,如果我这样做,我在保存更新时会遇到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);

如果你不做这样的事情,那么随着数据库的增长,你的问题会随着时间的推移而变得越来越糟 - 每当你要提取的数据量超过你需要的数量时,随着不必要数据的大小增加,所以浪费的时间用于提取您实际不需要的数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM