gpt4 book ai didi

c# - 使用 LINQPad 将数据插入 SQL CE 数据库,Linq-to-sql,随着时间的推移变得越来越慢,我能做些什么呢?

转载 作者:行者123 更新时间:2023-12-03 20:36:46 24 4
gpt4 key购买 nike

我在磁盘上有一个 SQL CE 4.0 数据库,还有一个 LINQPad我想用来填充该数据库的程序。

我正在使用内置(到 LINQPad)linq2sql 系统。我注意到随着时间的推移,插入一批行所需的时间越来越多,最终看起来程序已经慢到爬行。

是否有某种缓存或类似的东西会减慢它的速度?如果有的话,我能做些什么来避免这种减速?

这是我用来测试它的简单测试表:

CREATE TABLE dummy
(
id int not null primary key identity (1, 1),
value nvarchar(20) not null
)

和我的测试程序:
void Main()
{
for (int iteration = 1; iteration <= 1000; iteration++)
{
Stopwatch sw = Stopwatch.StartNew();
for (int row = 0; row < 100; row++)
dummy.InsertOnSubmit(new dummy { value = "row#" + row });
var create = sw.ElapsedMilliseconds;
SubmitChanges();
sw.Stop();
var total = sw.ElapsedMilliseconds;
Debug.WriteLine("iteration " + iteration + ", create=" + create + ", total=" + total);
}
}

这是示例输出:
iteration 1, create=1, total=52
iteration 2, create=0, total=41
iteration 3, create=0, total=53
iteration 4, create=0, total=45
...
iteration 86, create=0, total=181
iteration 87, create=0, total=218
iteration 88, create=0, total=172
iteration 89, create=4, total=192
...
iteration 167, create=0, total=387
iteration 168, create=0, total=427
iteration 169, create=0, total=496
iteration 170, create=0, total=425

如您所见,调用 SubmitChanges 所需的时间花费越来越多的时间,但我每次迭代都插入相同数量的实体。

请注意,我完全清楚我不会获得像批量插入或其他类似的速度,但我仍然希望尽可能避免这种减速。

还要注意,如果我现在重新运行程序,数据库中已经有很多行,时间又开始变低了:
iteration 1, create=1, total=51
iteration 2, create=0, total=50
iteration 3, create=0, total=45
iteration 4, create=0, total=45

所以在我看来,有些东西在内存中不断增长。

除了定期停止程序并重新启动它(我真正在做的事情可以做到,但我想避免它)之外,有什么我可以关闭、重置、转储等来解决这个问题的.

最佳答案

听起来您想从 LINQPad 中将数据批量复制到 SQL Server。这是我用来执行此操作的方法:

void BCP<TRow> (IEnumerable<TRow> rows)
{
if (rows.Count() == 0) return;
var dt = new DataTable ();
var metaTable = _db.Mapping.GetTable (typeof (TRow));
var columns = metaTable.RowType.DataMembers.Where (dm => dm.Association == null);
var transformers = new List<Func<TRow, object>>();
foreach (var columnX in columns)
{
var column = columnX;
dt.Columns.Add (column.Name, L2sToDataTable (column.Type));
transformers.Add (row => L2sToDataTable (row.GetType().GetField (column.Name).GetValue (row)));
}
foreach (var row in rows)
dt.Rows.Add (transformers.Select (t => t (row)).ToArray());

_db.Connection.Open();
Console.Write ("Bulk copying " + metaTable.TableName + "... ");
var bcp = new SqlBulkCopy ((SqlConnection)_db.Connection) { DestinationTableName = metaTable.TableName, BulkCopyTimeout = 300 };
bcp.BatchSize = 20;
bcp.NotifyAfter = 20;
bcp.SqlRowsCopied += (sender, args) => Console.Write (args.RowsCopied + " rows... ");
bcp.WriteToServer (dt);
_db.Connection.Close();
Console.WriteLine ("Done");
}

Type L2sToDataTable (Type l2sType)
{
if (l2sType == typeof (Binary)) return typeof (byte[]);
if (l2sType.IsGenericType && l2sType.GetGenericTypeDefinition() == typeof (Nullable<>)) return l2sType.GetGenericArguments()[0];
return l2sType;
}

object L2sToDataTable (object l2sValue)
{
if (l2sValue == null) return DBNull.Value;
if (l2sValue is Binary) return ((Binary) l2sValue).ToArray();
return l2sValue;
}

这避免了对象关系映射器(例如 LINQ-to-SQL)的缓存内存开销,同时利用了后者的元数据。

关于c# - 使用 LINQPad 将数据插入 SQL CE 数据库,Linq-to-sql,随着时间的推移变得越来越慢,我能做些什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21352274/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com