c# - 运行 linq 查询时 DbContext 超时

标签 c# entity-framework linq entity-framework-core asp.net5

我有以下异步方法来查询数据库上的某些数据。

private async Task<List<MyObject>> GetTotalConcert(DateTime d1, DateTime d2, string[] name)
        {
            using (RegistrationDbContext context = new RegistrationDbContext())
            {
                IQueryable<MyObject> results;

                results = (from t1 in context.Table1
                           join t2 in context.Table2 on t1.Id equals t2.Id
                           where (t2.CreatedOn >= d1 && t2.CreatedOn < d2)
                           && (name.Contains(t2.Name))
                           && t1.EventName.Equals("Concert")
                           select new MyObject
                           {
                               Id = t2.Id,
                               EventName = t1.EventName,
                               Status = t2.Status,
                               ProjectName = t2.Name
                           });

                return await results.Distinct().ToAsyncEnumerable().ToList();
            }
        }

在日期范围太宽的情况下,此代码会失败并出现超时异常。我尝试通过这样做来增加超时:

public class RegistrationDbContext : DbContext
    {
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            base.Database.SetCommandTimeout(300);

        }
        // Some more code here....
    }

我在这里做错了什么吗?如果我在数据库本身上运行 SQL 查询,则相同的日期范围需要接近 18 秒...

我正在使用 ASP.NET 5 MVC6 和 EF7。

对于这些时间范围太宽并且数据库需要更多时间返回数据的情况,如何摆脱超时异常?

最佳答案

该问题很可能与所谓的 Parameter Sniffing Problem 有关。 ,类似于EntityFramework LINQ query count fails but query returns result. How to optimize LINQ query?

您可以从链接获取帮助程序类的修改版本:

using System;
using System.Linq;
using System.Linq.Expressions;

public static class QueryableUtils
{
    public static IQueryable<T> WhereIn<T>(this IQueryable<T> source, Expression<Func<T, DateTime>> dateSelector, DateTime startDate, DateTime endDate)
    {
        var startCond = Expression.GreaterThanOrEqual(dateSelector.Body, Expression.Constant(startDate));
        var endCond = Expression.LessThan(dateSelector.Body, Expression.Constant(endDate));
        var predicate = Expression.Lambda<Func<T, bool>>(Expression.AndAlso(startCond, endCond), dateSelector.Parameters[0]);
        return source.Where(predicate);
    }

    public static IQueryable<T> WhereIn<T>(this IQueryable<T> source, Expression<Func<T, DateTime?>> dateSelector, DateTime startDate, DateTime endDate)
    {
        var startCond = Expression.GreaterThanOrEqual(dateSelector.Body, Expression.Constant(startDate, typeof(DateTime?)));
        var endCond = Expression.LessThan(dateSelector.Body, Expression.Constant(endDate, typeof(DateTime?)));
        var predicate = Expression.Lambda<Func<T, bool>>(Expression.AndAlso(startCond, endCond), dateSelector.Parameters[0]);
        return source.Where(predicate);
    }
}

然后将您的查询更改为:

results = (from t1 in context.Table1
           join t2 in context.Table2.WhereIn(x => x.CreatedOn, d1, d2) on t1.Id equals t2.Id
           where (name.Contains(t2.Name))
           && t1.EventName.Equals("Concert")
           select new MyObject
           {
               Id = t2.Id,
               EventName = t1.EventName,
               Status = t2.Status,
               ProjectName = t2.Name
           });

看看是否有帮助。

关于c# - 运行 linq 查询时 DbContext 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37034705/

相关文章:

asp.net - 使用通过 React GUI 触发的 Entity Framework 向数据库添加新条目时重复条目

c# - 我应该为任何方法结果做 Contract.Ensures 吗?

entity-framework - 使用 ADO.NET Entity Framework 编写 "queries"的经验法则

c# -  以 ANSI 格式查看时出现在我的 utf-8 文本文件的开头

.net - Entity Framework : Type "mapped as a complex type" Error

sql - 强制 LINQ to SQL 或 ENTITIES 发出 BETWEEN 运算符

c# - 尽管集合中的所有值均为 false,Linq Any 仍返回 true

c# - linq在特定条件下获取多个值

c# - 从用户控件调用的 GridView 在页面重新加载时为空

c# - DataBindingComplete 被多次调用