[英]How to send a limited amount of inserts at a time. C# System.Data.SQLite
我必須讀取 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();
}
}
}
}
}
通常,如果要處理IEnumerable<T>
中的n
個項目,則可以使用IEnumerable
擴展方法Skip
和Take
,其中跳過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
}
您可以使用庫MoreLinq的擴展方法Batch
:將源序列Batch
處理到大小的桶中。
如果你不想弄亂外部庫,你可以使用下面的方法,它是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
我想這個問題現在已經過時了,因為作業可能已經過去了。
但是,從代碼中可以明顯看出,第一次transaction.Commit();
被調用,交易將完成。 但是循環中沒有新的事務開始,所以下次該transaction.Commit();
被調用會發生錯誤,因為將不再有活動事務!
此外,循環后沒有代碼來處理任何不能被 10 整除的剩余行。即使原始循環代碼有效,它也可能留下未提交的行,而這些行不會被正確提交。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.