我在实体框架中读到here,如果执行包含操作,则会降低性能:
包含在SQL中转换为“WHERE IN”,导致性能下降“
现在我有近10个表有10列,在获取记录时我使用Contains近8列。
我的问题是真的吗?如果是,那替代方案是什么?
答案 0 :(得分:2)
是包含()会严重降低性能。
所以你可以尝试下面提到的解决方案。
我们能够通过添加中间表并从需要使用Contains子句的LINQ查询连接该表来解决EF Contains问题。通过这种方法我们得到了惊人的结果。我们有一个大的EF模型,并且在预编译EF查询时不允许使用“Contains”,对于使用“Contains”子句的查询,我们的性能非常差。
概述:
在SQL Server中创建一个表 - 例如HelperForContainsOfIntType,其HelperID为Guid数据类型,ReferenceID为int数据类型列。根据需要使用不同数据类型的ReferenceID创建不同的表。
为EF模型中的HelperForContainsOfIntType和其他此类表创建实体/实体集。根据需要为不同的数据类型创建不同的Entity / EntitySet。
在.NET代码中创建一个辅助方法,它接受IEnumerable的输入并返回一个Guid。此方法生成一个新的Guid,并将IEnumerable中的值与生成的Guid一起插入HelperForContainsOfIntType。接下来,该方法将此新生成的Guid返回给调用者。要快速插入HelperForContainsOfIntType表,请创建一个存储过程,该过程接受值列表的输入并进行插入。见Table-Valued Parameters in 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子句中使用的值调用帮助程序方法,并使Guid在查询中使用。 例如:
var containsHelperID = dbHelper.InsertIntoHelperForContainsOfIntType(new int[] { 1, 2, 3 });
var result = _selectCustomers(_dbContext, containsHelperID).ToList();
我是从 Here
那里得到的