C# 实体框架超时

C# 实体框架超时,c#,asp.net,entity-framework,entity-framework-4,connection-string,C#,Asp.net,Entity Framework,Entity Framework 4,Connection String,我使用实体框架(EF)在使用需要30秒以上才能完成的函数导入时超时。我尝试了以下操作,但未能解决此问题: 我将defaultcommand Timeout=300000添加到项目中App.Config文件中的连接字符串中,该项目具有建议的EDMX文件 这是我的连接字符串的外观: 我尝试直接在我的存储库中设置CommandTimeout,如下所示: private TrekEntities context = new TrekEntities(); public IEnumerable<

我使用实体框架(EF)在使用需要30秒以上才能完成的函数导入时超时。我尝试了以下操作,但未能解决此问题:

我将
defaultcommand Timeout=300000
添加到项目中App.Config文件中的连接字符串中,该项目具有建议的EDMX文件

这是我的连接字符串的外观:


我尝试直接在我的存储库中设置CommandTimeout,如下所示:

private TrekEntities context = new TrekEntities();

public IEnumerable<TrekMatches> GetKirksFriends()
{
    this.context.CommandTimeout = 180;
    return this.context.GetKirksFriends();
}

显然,在连接字符串中设置超时设置对其没有影响。

在EF连接字符串中指定默认命令超时存在已知错误

从连接字符串中删除该值,并在数据上下文对象本身上设置该值。如果从连接字符串中删除冲突的值,这将起作用

实体框架核心1.0: 实体框架6: 实体框架5: 实体框架4及以下:
如果使用的是DbContext,请使用以下构造函数设置命令超时:

public class MyContext : DbContext
{
    public MyContext ()
    {
        var adapter = (IObjectContextAdapter)this;
        var objectContext = adapter.ObjectContext;
        objectContext.CommandTimeout = 1 * 60; // value in seconds
    }
}

如果您使用的是
DbContext
和EF v6+,也可以使用:

this.context.Database.CommandTimeout = 180;

这就是我的资金。也许这会对某人有所帮助:

现在我们开始:

如果使用LINQ和EF查找列表中包含的某些精确元素,如下所示:

await context.MyObject1.Include("MyObject2").Where(t => IdList.Contains(t.MyObjectId)).ToListAsync();
在IdList包含多个Id之前,一切都正常

如果列表仅包含一个Id,则会出现“超时”问题。要解决此问题,请使用if条件检查IdList中的Id数

例如:

if (IdList.Count == 1)
{
    result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.FirstOrDefault()==t. MyObjectId).ToListAsync();
}
else
{
    result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.Contains(t. MyObjectId)).ToListAsync();
}
说明:


只需尝试使用Sql事件探查器并检查Entity FrameError生成的Select语句

通常我在事务中处理操作。正如我所经历的,设置上下文命令timeout是不够的,但是事务需要一个带有timeout参数的构造函数。我必须设置两个超时值,它才能正常工作

int? prevto = uow.Context.Database.CommandTimeout;
uow.Context.Database.CommandTimeout = 900;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) {
...
}
在函数结束时,我将命令超时设置为prevto中的上一个值


使用EF6,我知道这是一个非常旧的线程运行,但EF仍然没有修复这个问题。对于使用自动生成的
DbContext
的用户,可以使用以下代码手动设置超时

public partial class SampleContext : DbContext
{
    public SampleContext()
        : base("name=SampleContext")
    {
        this.SetCommandTimeOut(180);
    }

    public void SetCommandTimeOut(int Timeout)
    {
        var objectContext = (this as IObjectContextAdapter).ObjectContext;
        objectContext.CommandTimeout = Timeout;
    }

如果您使用的是像我这样的实体框架,则应按如下方式定义启动类超时:

 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(180)));
services.AddDbContext(options=>options.UseSqlServer(Configuration.GetConnectionString(“DefaultConnection”),o=>o.CommandTimeout(180));

.Net Core(NetCore)中,使用以下语法将超时时间从默认的30秒更改为90秒:

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        this.Database.SetCommandTimeout(90); // <-- 90 seconds
    }
}
公共类DataContext:DbContext
{
公共数据上下文(DbContextOptions):基本(选项)
{

此.Database.SetCommandTimeout(90);//将以下内容添加到我的存储过程中,解决了我的超时错误:

SET NOCOUNT ON;
SET ARITHABORT ON;

对于EntityFramework6,我使用这个注释,效果很好

  public partial class MyDbContext : DbContext
  {
      private const int TimeoutDuration = 300;

      public MyDbContext ()
          : base("name=Model1")
      {
          this.Database.CommandTimeout = TimeoutDuration;
      }
       // Some other codes
    }
CommandTimeout参数是设置超时的可为空整数 值为秒,如果设置为null或未设置,则将使用默认值 您使用的提供者的值


Remove“from connection string在EF连接字符串中也引用@hamlin11,这是定义什么部分是连接字符串,什么部分是EF元数据所必需的。保留
在字符串中。我的建议是,在增加超时之前,首先调查EF超时的原因。在我们的案例中,我们意识到我们需要向一些表添加
非聚集的
索引,这为我们解决了超时问题。我正在与MS支持部门合作解决SQL超时问题-这是在数据库停止运行时我被告知所有Azure PaaS服务(PaaS网站和SQL Azure等)有一个230秒的通用超时时间,即使您手动设置超时时间,它也始终优先。这是为了保护多租户PaaS基础结构的资源。@ErickPetru,因此您可以轻松地将其更改为不同的分钟数:),而且如果编译器优化了乘法,我也不会太惊讶!@JoelVerhagen,不要惊讶。这里有一个关于自动优化何时发生的很好的解释:。在这种情况下,我认为甚至会发生这种情况(因为它们是两个文本值)​​), 但老实说,我觉得这样的代码有点奇怪。嗯……孩子们都饿了……谁在乎1*60?@ErikPetru,这实际上是一种非常普遍的做法,使代码更具可读性。鉴于我的
DbContext
派生类是从
edmx
文件自动生成的,处理这个问题的最佳方法是什么?我如何实现这一点他在使用edmx?在哪个版本的EntityFramework中修复了这个问题?我找不到它的EF错误。我不认为这是一个错误,但根据设计,请参阅此处的备注部分,因为有些设置以毫秒为单位,有些设置以秒为单位,我查找了它,CommandTimeout以秒为单位。在EntityFramework 7中,您可以在DbContext/IdentityDbContext的con中设置它structor:
this.Database.SetCommandTimeout(180);
根本不是一个好方法。我过去常常添加很多事务作用域,这对我来说在项目中是一个噩梦。最终用单个SAVEChanges()替换了所有事务作用域在EF 6+中。检查此项。此答案应具有更高的投票权。我尝试了所有不同的方法来增加超时,但仅当我同时设置上下文命令超时和事务范围时,它才起作用。在部分的末尾添加缺少的}。
public partial class SampleContext : DbContext
{
    public SampleContext()
        : base("name=SampleContext")
    {
        this.SetCommandTimeOut(180);
    }

    public void SetCommandTimeOut(int Timeout)
    {
        var objectContext = (this as IObjectContextAdapter).ObjectContext;
        objectContext.CommandTimeout = Timeout;
    }
 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(180)));
public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        this.Database.SetCommandTimeout(90); // <-- 90 seconds
    }
}
SET NOCOUNT ON;
SET ARITHABORT ON;
  public partial class MyDbContext : DbContext
  {
      private const int TimeoutDuration = 300;

      public MyDbContext ()
          : base("name=Model1")
      {
          this.Database.CommandTimeout = TimeoutDuration;
      }
       // Some other codes
    }