首页 > 解决方案 > 如何在 foreach 循环中并行执行方法或 DML 以加快执行时间?

问题描述

我有以下代码查询表并更新其中的行,然后根据以前的查询执行插入:

private void button1_Click(object sender, EventArgs e)
        {
            doDBDML();
        }

private void doDBDML()
        {
            using (ThreadingDBEntities db = new ThreadingDBEntities())
            {
                var rows = db.people.Where(x => x.id == null).ToList();

                foreach (person p in rows) // how to execute it in parallel.
                {
                    p.id = p.personID; // update null value.

                    // execute stored procedure which has output parameter to get id (return existing id or insert new row and get its id).
                    ObjectParameter outParam = new ObjectParameter("p_id", typeof(Int32));
                    db.sp_getCompanyId(p.company, outParam);

                    // and new row. this depends on current person object id , and company id which has returned from stored precedure.
                    User_Company userComp = new User_Company();
                    userComp.person_Id = p.personID;
                    userComp.Company_Id = (Int32) outParam.Value;

                    db.SaveChanges();
                }
            }
        }

存储过程是

CREATE PROCEDURE [dbo].[sp_getCompanyId]
    @p_ocmpany_Name nvarchar(255),
    @p_id int output
AS
    SELECT @p_id = id
    from Company
    where Company_name = @p_ocmpany_Name

    if @p_id is null 
    begin
        begin transaction;
        insert into Company (company_name) values (@p_ocmpany_Name);
        select @p_id = SCOPE_IDENTITY();
        commit transaction; 
    end;
RETURN @p_id

这工作正常,但问题是: - 查询返回大量行,因此执行需要很长时间才能执行,如何加速它?如何调用上述 doDBDML 方法将其作为并行或批量执行来执行?

我的问题与 Windows 窗体应用程序有关,但是我也想知道该解决方案是否适用于 asp.net

标签: c#sql-serverwinformsentity-frameworklinq

解决方案


正如 TomC 和 TheGeneral 所说,您解决问题的解决方案可能有问题。如果您想检查通过简单的并行性可以获得多少速度,您可以查看

Parallel.Foreach

https://msdn.microsoft.com/de-de/library/dd460720(v=vs.100).aspx

但也要记住,如果您使用多个线程,您可能会在数据库中创建重复项。例如

Thread #1 - enters stored-procedure
Thread #1 - cannot find customer "customerA" -> start transaction for creating a new customer
Thread #2 - enters stored-procedure
Thread #2 - cannot find customer "customerA" -> start transaction
Thread #2 - finish transaction -> return id '42'
Thread #1 - finish transaction -> return id '666'

现在您有同一个客户的两个客户数据集

ID  | Name
42  | customerA
666 | customerA

推荐阅读