为什么 Contains() 运算符会降低实体框架的 Linq 查询?



我在这里读到,在实体框架中,如果执行包含操作,会降低性能:

Contains在SQL中转换为"WHERE IN",导致性能下降">

现在我有近10个表有10列,在获取记录时,我使用Contains处理近8列。

我的问题是绝对正确的吗?如果是,替代方案是什么?

Contains()将严重降低性能。

所以您可以尝试下面提到的解决方案

我们能够通过添加一个中间表并从需要使用Contains子句的LINQ查询中联接该表来解决EF Contains问题。我们用这种方法取得了惊人的结果。我们有一个大型EF模型,由于预编译EF查询时不允许使用"Contains",因此使用"Contines"子句的查询性能非常差。

概述:

  1. 在SQL Server中创建一个表,例如HelperForContainsOfIntType,HelperID为Guid数据类型,ReferenceID为int数据类型列。根据需要使用不同数据类型的ReferenceID创建不同的表。

  2. 为HelperForContainsOfIntType和EF模型中的其他此类表创建实体/实体集。根据需要为不同的数据类型创建不同的Entity/EntitySet。

  3. 在.NET代码中创建一个助手方法,该方法接受IEnumerable的输入并返回Guid。此方法生成一个新的Guid,并将IEnumerable中的值与生成的Guid一起插入HelperForContainsOfIntType中。接下来,该方法将这个新生成的Guid返回给调用者。为了快速插入HelperForContainsOfIntType表,请创建一个存储过程,该过程接受值列表的输入并进行插入。请参阅SQL Server 2008(ADO.NET)中的表值参数。为不同的数据类型创建不同的帮助程序,或者创建一个通用帮助程序方法来处理不同数据类型。

创建一个EF编译的查询,类似于下面的内容:

static Func<MyEntities, Guid, IEnumerable<Customer>> _selectCustomers =
CompiledQuery.Compile(
(MyEntities db, Guid containsHelperID) =>
from cust in db.Customers
join x in db.HelperForContainsOfIntType on cust.CustomerID equals x.ReferenceID where x.HelperID == containsHelperID
select cust 
);

使用Contains子句中要使用的值调用helper方法,并获取要在查询中使用的Guid例如:

var containsHelperID = dbHelper.InsertIntoHelperForContainsOfIntType(new int[] { 1, 2, 3 });
var result = _selectCustomers(_dbContext, containsHelperID).ToList();

我是从这里得到的

最新更新