Linq to Sql Udf 调用比普通调用更快 Ado.net

Linq to Sql Udf call faster than plain Ado.net

我们有一个遗留应用程序,我们在其中调用数据库中的用户定义函数。这个 Udf returns 一个非常大的 xml 字符串(大约 1971540 个字符)。令人惊讶的是,linq to sql 的 ExecuteMethodCall 运行得非常快,而普通的 Ado.Net DbDataReader.GetString() 很慢!!!

我们已经对调用进行了基准测试,L2S 可以在 4 秒内获取它,而普通 Ado.net DbDataReader.GetString() 可以在大约 37 秒内获取它。

查看 L2S 代码,它似乎使用相同的 DbDataReader.GetString() 方法,尽管是通过动态生成的 IL 代码。 http://referencesource.microsoft.com/#System.Data.Linq/SqlClient/Reader/ObjectReaderCompiler.cs,b2f6633a6c502138

我想了解是什么让 L2S 能够在如此短的时间内读取如此庞大的数据?

请注意,即使在第一次调用时它也运行得足够快,所以它可能不是缓存魔法。

编辑

using (DbConnection con = _dataContext.Database.Connection)
{
    DbCommand cmd = con.CreateCommand();
    cmd.CommandText = sql;
    cmd.Transaction = _dataContext.Database.CurrentTransaction.UnderlyingTransaction;

    parameters.Cast<System.Data.SqlClient.SqlParameter>().ToList().ForEach(x => cmd.Parameters.Add(x));
    cmd.CommandTimeout = 500;

    if (con.State != System.Data.ConnectionState.Open)
        con.Open();
    using (var reader = cmd.ExecuteReader(System.Data.CommandBehavior.SequentialAccess | System.Data.CommandBehavior.SingleResult | System.Data.CommandBehavior.SingleRow))
    {
        if (reader.Read())
        {
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            var data = reader.GetString(0);

            sw.Stop();
            var et = sw.Elapsed.TotalSeconds;
        }
    }
}

此致。

最终经过大量的思考和调整...原来是 MARS 配置的问题!!

MARS 在我们最新的重构代码中打开(我认为是 EF 的默认行为),因为它在 Linq to sql 连接字符串中不存在。

一旦我们从连接字符串中删除 "MultipleActiveRecordSets=True;",它就可以正常工作。不确定为什么删除 MARS 会起作用。

希望对以后遇到类似问题的人有所帮助。