使用带有存储过程的Linq比使用生成SQL的Linq更好吗?

时间:2011-06-30 10:53:32

标签: c# linq sql-server-2005 linq-to-sql

我对Linq的工作原理并不了解。我刚刚尝试了一些Linq的例子,这就是我不确定并提出问题的原因。

一般来说,网上的Linq很慢。我的问题是,带有SP的Linq是否比使用Generated SQL的Linq提供更好的性能?或两者都相同。

请指导。

2 个答案:

答案 0 :(得分:7)

因为Linq-to-Sql使用QueryProviderExpression转换为SQL语句,所以它必须为该提供程序执行的每个查询执行此操作(除非查询是预编译的[更多内容]再向下])。所以,例如在基本层面:

var people = context.People.Where(p => p.Name == "Matt");

Linq-to-Sql需要将表达式p => p.Name == "Matt"转换为表达式树,然后表达式树转换为SQL语句,类似于:

SELECT t0.Name FROM People t0 WHERE t0.Name = 'Matt'

对Sql Server执行时的查询,而Sql Server又需要为查询生成执行计划并针对该表运行以获取结果。它非常有效地为正确的作业创建正确的查询,并支持更多的临时数据查询方法。

使用存储过程,Linq-to-Sql不必生成表达式树,并从中生成sql,而设计器生成的类具有将方法中的参数传递给存储过程所需的全部信息。

从这个意义上讲,它使用存储过程的效率更高,但是你无法进行这些经常有用的即席查询。

您可能会发现它真的归结为在您的数据库中使用sprocs与直接查询的偏好(与您的DBA讨论)。

编译查询允许您获得预编译语句的好处(查询仅生成一次),因此后续查询将使用先前编译的查询。一个例子是:

public IQueryable<Product> GetProduct(int id)
{
    // Normal query, expression tree and sql generated each time it is
    // it is executed against the data source.
    return context.Products.Where(p => p.Id == id);
}

而编译的查询:

private static readonly Func<DataContext, int, IQueryable<Product>> ProductById = 
    CompiledQuery.Compile((context, id) => 
        context.Products.Where(p => p.Id == id));

public IQueryable<Product> GetProduct(int id)
{
    return ProductById(context, id);
}

后者将使用预编译查询,因此它只生成表达式树和sql一次。

答案 1 :(得分:1)

当然,这完全取决于您的查询以及需要获取的数据量。

查询越复杂,LINQ生成的SQL效率就越低。

因此,如果您的查询非常复杂/沉重,我建议您使用存储过程/视图,因为那时您将使用数据库服务器的强大功能,而不是LINQ2SQL生成的效率较低的SQL。