C# foreachasync和带有实体记录的for循环之间的区别?

C# foreachasync和带有实体记录的for循环之间的区别?,c#,entity-framework,C#,Entity Framework,我很想知道下面两个语句之间的区别是什么,以及为什么.ForEacHAsync不能用于创建新行,而for循环可以 这项工作并添加了新的唱片产品 var recordProducts = context.RecordsProducts .Where(i => i.RecordId == model.OldRecordId); foreach (var rp in recordProducts) { var new

我很想知道下面两个语句之间的区别是什么,以及为什么.ForEacHAsync不能用于创建新行,而for循环可以

这项工作并添加了新的唱片产品

var recordProducts = context.RecordsProducts
            .Where(i => i.RecordId == model.OldRecordId);

        foreach (var rp in recordProducts)
        {
            var newRecordProduct = new RecordProduct
            {
                IsActive = true,
                RecordId = model.RecordId,
                ProductId = rp.ProductId,
                DefendantId = rp.DefendantId,
                Annotation = rp.Annotation
            };
            context.RecordsProducts.Add(newRecordProduct);
        }
这并不重要

var recordProducts = context.RecordsProducts
            .Where(i => i.RecordId == model.OldRecordId)
            .ForEachAsync(a =>
            {
                var newRecordProduct = new RecordProduct
                {
                    IsActive = true,
                    RecordId = model.RecordId,
                    ProductId = a.ProductId,
                    DefendantId = a.DefendantId,
                    Annotation = a.Annotation
                };
                context.RecordsProducts.Add(newRecordProduct);
            }
        );

在第一个示例中,您的IQueryable recordProducts将以同步方式而不是异步方式进行计算,因此它将阻止对IQueryable.GetEnumerator…MoveNext的隐藏调用中的线程

而在第二个示例中,.ForEachAsync扩展方法将异步运行匿名函数,与此等效:

IQueryable<RecordProduct> list = await context.RecordsProducts
    .Where(i => i.RecordId == model.OldRecordId);

using( DataReader rdr = await ExecuteQueryAsDataReader( list ) )
{
    while( await rdr.ReadAsync() )
    {
        await ForEachAsyncBodyHere();
    }
}
我认为这两段代码都不一定好-我认为最好的方法是使用ToListSync一次异步加载所有数据,然后使用普通的同步foreach添加每个记录,然后等待保存更改同步:


在第一个示例中,您的IQueryable recordProducts将以同步方式而不是异步方式进行计算,因此它将阻止对IQueryable.GetEnumerator…MoveNext的隐藏调用中的线程

而在第二个示例中,.ForEachAsync扩展方法将异步运行匿名函数,与此等效:

IQueryable<RecordProduct> list = await context.RecordsProducts
    .Where(i => i.RecordId == model.OldRecordId);

using( DataReader rdr = await ExecuteQueryAsDataReader( list ) )
{
    while( await rdr.ReadAsync() )
    {
        await ForEachAsyncBodyHere();
    }
}
我认为这两段代码都不一定好-我认为最好的方法是使用ToListSync一次异步加载所有数据,然后使用普通的同步foreach添加每个记录,然后等待保存更改同步:


“不工作”是一个非常糟糕的问题描述。到底发生了什么你没有预料到的事情?任何编译器错误、异常、错误结果?不,只是在数据库中没有创建行。不工作是一个非常糟糕的问题描述。到底发生了什么你没有预料到的事情?任何编译器错误、异常、错误结果吗?不,只是行没有在DB中创建。如果我不使用第一部分中的等待,那么它返回一个任务,任务和列表之间的区别是什么?当U.S.1186050在.NET中的任务相当于在JavaScript中的承诺和C++中的未来。在回复中解释承诺是不可行的。我建议改为读这篇文章:如果我不使用第一部分的等待,那么它返回一个任务,任务和列表之间的区别是什么?C++中的任务UsR1186050相当于JavaScript中的承诺和C++中的未来。在回复中解释承诺是不可行的。我建议阅读本文:
List<RecordProduct> list = await context.RecordsProducts
    .Where(i => i.RecordId == model.OldRecordId)
    .ToListAsync();

foreach( RecordProduct rp in list )
{
    context.RecordsProduct.Add( ... );
}

await context.SaveChangesAsync();