相关疑难解决方法(0)

在Entity Framework LINQ查询中使用IEnumerable.Contains时如何避免查询计划重新编译?

我使用Entity Framework(v6.1.1)执行以下LINQ查询:

private IList<Customer> GetFullCustomers(IEnumerable<int> customersIds)
{
    IQueryable<Customer> fullCustomerQuery = GetFullQuery();
    return fullCustomerQuery.Where(c => customersIds.Contains(c.Id)).ToList();
}
Run Code Online (Sandbox Code Playgroud)

这个查询被翻译成相当不错的SQL:

SELECT 
[Extent1].[Id] AS [Id], 
[Extent1].[FirstName] AS [FirstName]
-- ...
FROM [dbo].[Customer] AS [Extent1]
WHERE [Extent1].[Id] IN (1, 2, 3, 5)
Run Code Online (Sandbox Code Playgroud)

但是,我在查询编译阶段获得了非常显着的性能影响.呼叫:

ELinqQueryState.GetExecutionPlan(MergeOption? forMergeOption) 
Run Code Online (Sandbox Code Playgroud)

占用每个请求约50%的时间.深入研究,结果是每次我传递不同的customersIds时都会重新编译查询.根据MSDN文章,这是一个正常现象,因为IEnumerable的是在查询中使用被认为是挥发性的,并且是缓存的SQL的一部分.这就是为什么SQL对于customersIds的每个不同组合都是不同的,并且它总是具有用于从缓存中获取编译查询的不同哈希.

现在问题是:如何在仍然查询多个customersIds时避免重新编译?

linq performance linq-to-entities entity-framework

31
推荐指数
2
解决办法
3298
查看次数

与原始SQL执行时间相比,Entity Framework的性能开销是多少?

在我的应用程序(EF6 + SQL Server)中,我动态创建EF查询以启用丰富的搜索功能.

这些查询是通过链接一堆Where()谓词,并使用少量聚合将结果投影到已知的CLR类型中创建的.在所有情况下,EF都会生成一个返回少量结果的SQL查询(大约10个).

使用SQL事件探查器我可以看到这些生成的查询在由数据库执行时的执行时间只有几毫秒.但是,除非查询简单,否则总执行时间(从我的代码调用ToList()或Count())在几百毫秒内!代码在发布模式下构建,无需附加调试器即可进行测试.

任何人都可以给我任何暗示我的方法可能有什么问题吗?与原始SQL执行时间相比,EF的开销是否有可能达到两个数量级?

编辑:

这些是我用来过滤结果集的一些代码示例:

if (p.PriceMin != null)
    query = query.Where(a => a.Terms.Any(t => t.Price >= p.PriceMin.Value));

if (p.StartDate != null && p.EndDate != null)
    query = query.Where(a => a.Terms.Any(t => t.Date >= p.StartDate.Value && t.Date <= p.EndDate.Value));

if (p.DurationMin != null)
    query = query.Where(a => a.Itinerary.OfType<DayElement>().Count() > p.DurationMin.Value - 2);

if (p.Locations != null && p.Locations.Count > 0)
{
    var locs = p.Locations.Select(l => new Nullable<int>(l)).ToList();
    query = query.Where(a => a.Itinerary.OfType<MoveToElement>().Any(e => locs.Contains(e.LocationId)) || …
Run Code Online (Sandbox Code Playgroud)

c# performance entity-framework

6
推荐指数
1
解决办法
3225
查看次数

错误 CS1929“int[]”不包含“包含”的定义

错误 CS1929“int[]”不包含“Contains”的定义,并且最佳扩展方法重载“Queryable.Contains<int?>(IQueryable<int?>, int?)”需要类型为“IQueryable<int”的接收器?

一旦我尝试运行代码,就会出现此错误,我不知道如何修复它。这是代码

public void SendModelPallet(string IDs, StorageContext db)
{
    int[] ids = ViewModelsUtils.processIDs(IDs);
    PalletBoxes = db.ExternStoragePlaces.Where(c => ids.Contains(c.PalletPlaceID)).ToList();
    this.db = db;
}
Run Code Online (Sandbox Code Playgroud)

提前致谢

c#

2
推荐指数
1
解决办法
9001
查看次数