【问题标题】:How do you force linq to sql to use the correct data type for sql parameters?如何强制 linq to sql 为 sql 参数使用正确的数据类型?
【发布时间】:2009-11-04 22:51:22
【问题描述】:

我有一种情况,即针对数百万行表运行的某个 linq 查询需要很长时间才能运行。我剖析了 linq 查询输出,发现它使用错误的数据类型为 where 子句创建参数。例如,一个字段在数据库中被定义为 Char(12),但它与之比较的参数被声明为 NVarChar(12)。一旦我将查询更改为使用 Char 而不是 NVarChar,它就会按应有的方式运行亚秒级。有没有办法让 linq to sql 使用 .dbml 文件中为该列定义的正确数据类型?我仔细检查并在数据上下文 .dbml 文件中将其定义为 DbType="Char(12)"。

【问题讨论】:

  • 我想知道你是否有一个糟糕的缓存执行计划,因为 nvarchar(12) 和 char(12) 不应该有很大的不同。至少我认为他们不应该这样做。
  • 经过相当多的测试,它确实做到了。我在每次运行之前清除了查询缓存,仅通过更改数据类型,它就从 4 秒缩短到了 20 毫秒。我什至将我的 linq to sql 调用转换为一个普通的旧 sql 查询,并使用数据上下文的 .ExecuteQuery() 方法来运行它,它运行得很快。这绝对是导致 SQL 忽略表上的索引的数据类型转换问题。

标签: sql-server linq-to-sql parameters types


【解决方案1】:

您可以直接获取命令并重置其上的参数类型(在您的情况下为 ansi-string)。

http://msdn.microsoft.com/en-us/library/system.data.linq.datacontext.getcommand.aspx http://msdn.microsoft.com/en-us/library/system.data.dbtype.aspx

然后您可能会对该命令调用 ExecuteReader,从而产生一个 DbDataReader。您可以将此 DbDataReader 交给 datacontext 的 Translate 方法,它会为您提供您期望从 linq 获得的 IEnumerable<T>

http://msdn.microsoft.com/en-us/library/bb534213.aspx


性能问题是由于查询参数的类型与查询优化器选择的索引不同。接下来发生的是将整个索引转换为参数的类型。每次发出查询时都会执行此操作 - 转换不会等待以后的查询。

在将字符串集合发送到数据库时,我通常会看到这种行为:

  //this query will get correct parameter type
db.Customers.Where(c => c.Name == "Bob")
  //this query can get incorrect parameter type
List<string> names = new List<string>(){"Amy", "Bob"};
db.Customers.Where(c => names.Contains(c.Name));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多