如何一次发送有限数量的插入。 C#System.Data.SQLite

问题描述 投票:-6回答:3

我必须读取一个CSV文件(这不是问题),一次做10个插入。我不知道CSV文件有多少行。我尝试制作一个循环并且每个MOD 10发送一个提交,但是在两三次之后程序会出错。我没有想法如何解决这个问题。

编辑:

对不起,我正在使用我的手机,我的代码是:


using (var connection = new SqliteConnection("conn-string"))
{
    connection.Open();
    using (var transaction = connection.BeginTransaction())
    {
        for (int i = 0; i < listCode.Count; i++)
        {
            string sql = $"insert into table1 (code) values ({listCode[i]})";

            using (var command = new SqliteCommand(sql, connection))
            {
                command.ExecuteNonQuery();

                if ( i % 10 == 9)
                {
                    transaction.Commit();
                 }

            }
        }
    }
}
c# commit system.data.sqlite
3个回答
0
投票

一般来说,如果你想在n中处理IEnumerable<T>项目的数量,你可以使用IEnumerable扩展方法,SkipTake的组合,你跳过iteration * n项目,然后在循环中从列表中获取n项目。

请注意,如果我们在每次迭代时通过n递增循环变量,那么这将成为我们传递给Skip的值。此外,如果剩余少于n项目,Take(n)将返回所有剩余项目。

例如:

// items would be the list of results from reading your csv file. Pseudocode:
List<SomeType> items = GetCSVItems(csvFilePath);

// Set this to the number of items we want to process in each batch
int batchCount = 10;

// To process a batch of 'batchCount' number of items, we first Skip(iteration * batchCount) 
// items in our list, and then we Take(batchCount) items from the list for our next batch
for (int i = 0; i < items.Count; i += batchCount)
{
    List<SomeType> itemBatch = items.Skip(i).Take(batchCount).ToList();

    // Process itemBatch here
}

0
投票

您可以使用库Batch的扩展方法MoreLinq:将源序列批量化为大小的存储桶。

如果你不想搞乱外部库,你可以使用下面的方法,这是Batch的轻量级版本。

public static IEnumerable<IEnumerable<TSource>> BatchForward<TSource>(
    this IEnumerable<TSource> source, int size)
{
    if (source == null) throw new ArgumentNullException(nameof(source));
    if (size <= 0) throw new ArgumentOutOfRangeException(nameof(size));
    var counter = 0;
    var batchVersion = 0;
    using (var enumerator = source.GetEnumerator())
    {
        while (enumerator.MoveNext())
        {
            counter++;
            batchVersion++;
            if ((counter - 1) % size == 0)
                yield return GetInnerEnumerable(enumerator, batchVersion);
        }
        batchVersion++;
    }
    IEnumerable<TSource> GetInnerEnumerable(IEnumerator<TSource> enumerator, int version)
    {
        while (true)
        {
            if (version != batchVersion)
                throw new InvalidOperationException("Enumeration out of order.");
            yield return enumerator.Current;
            if (counter % size == 0) break;
            if (!enumerator.MoveNext()) break;
            counter++;
        };
    }
}

用法示例:

foreach (var batch in Enumerable.Range(1, 22).BatchForward(5))
{
    Console.WriteLine($"{String.Join(", ", batch)}");
}

输出:

1, 2, 3, 4, 5 6, 7, 8, 9, 10 11, 12, 13, 14, 15 16, 17, 18, 19, 20 21, 22


0
投票

我想这个问题现在已经过时了,因为家庭作业可能已经过去了。

但是,从代码中可以明显看出,第一次调用transaction.Commit();时,交易将完成。但是在循环中没有启动新事务,所以下次调用transaction.Commit();时会发生错误,因为不再有活动事务了!

此外,在循环之后没有代码来处理任何不能被10整除的剩余行。即使原始循环代码有效,它也可能留下未提交的未提交的行。

© www.soinside.com 2019 - 2024. All rights reserved.