实体框架超时

发布于 2024-11-13 07:16:58 字数 1730 浏览 1 评论 0原文

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

我将 Default Command Timeout=300000 添加到项目中 App.Config 文件的连接字符串中,该文件具有按照此处建议的 EDMX 文件。

这就是我的连接字符串的样子:

<add 
    name="MyEntityConnectionString" 
    connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|
       res://*/MyEntities.msl;
       provider=System.Data.SqlClient;provider connection string=&quot;
       Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
       Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
       MultipleActiveResultSets=True;Default Command Timeout=300000;&quot;"
    providerName="System.Data.EntityClient" />

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

private TrekEntities context = new TrekEntities();

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

我还能做些什么来使 EF 免于超时?这只发生在非常大的数据集上。对于小数据集,一切都可以正常工作。

这是我遇到的错误之一:

System.Data.EntityCommandExecutionException:执行命令定义时发生错误。有关详细信息,请参阅内部异常。 ---> System.Data.SqlClient.SqlException:超时已过期。操作完成之前超时时间已过,或者服务器没有响应。


好吧——我成功了,但发生的事情很愚蠢。我将连接字符串设置为 Default Command Timeout=300000 并将 CommandTimeout 设置为 180。当我从连接字符串中删除 Default Command Timeout 时,它起作用了。因此,答案是在上下文对象的存储库中手动设置 CommandTimeout,如下所示:

this.context.CommandTimeout = 180;

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

I am getting timeouts using the Entity Framework (EF) when using a function import that takes over 30 seconds to complete. I tried the following and have not been able to resolve this issue:

I added Default Command Timeout=300000 to the connection string in the App.Config file in the project that has the EDMX file as suggested here.

This is what my connection string looks like:

<add 
    name="MyEntityConnectionString" 
    connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|
       res://*/MyEntities.msl;
       provider=System.Data.SqlClient;provider connection string="
       Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
       Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
       MultipleActiveResultSets=True;Default Command Timeout=300000;""
    providerName="System.Data.EntityClient" />

I tried setting the CommandTimeout in my repository directly like so:

private TrekEntities context = new TrekEntities();

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

What else can I do to get the EF from timing out? This only happens for very large datasets. Everything works fine with small datasets.

Here is one of the errors I'm getting:

System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.


OK - I got this working and it's silly what happened. I had both the connection string with Default Command Timeout=300000 and the CommandTimeout set to 180. When I removed the Default Command Timeout from the connection string, it worked. So the answer is to manually set the CommandTimeout in your repository on your context object like so:

this.context.CommandTimeout = 180;

Apparently setting the timeout settings in the connection string has no effect on it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

み零 2024-11-20 07:16:59

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

http://bugs.mysql.com/bug.php?id=56806

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

Entity Framework Core 1.0:

this.context.Database.SetCommandTimeout(180);

Entity Framework 6:

this.context.Database.CommandTimeout = 180;

Entity Framework 5:

((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180;

Entity Framework 4 及以下版本:

this.context.CommandTimeout = 180;

There is a known bug with specifying default command timeout within the EF connection string.

http://bugs.mysql.com/bug.php?id=56806

Remove the value from the connection string and set it on the data context object itself. This will work if you remove the conflicting value from the connection string.

Entity Framework Core 1.0:

this.context.Database.SetCommandTimeout(180);

Entity Framework 6:

this.context.Database.CommandTimeout = 180;

Entity Framework 5:

((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180;

Entity Framework 4 and below:

this.context.CommandTimeout = 180;
执笏见 2024-11-20 07:16:59

如果您使用的是 DbContext,请使用以下构造函数来设置命令超时:

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

If you are using a DbContext, use the following constructor to set the command timeout:

public class MyContext : DbContext
{
    public MyContext ()
    {
        var adapter = (IObjectContextAdapter)this;
        var objectContext = adapter.ObjectContext;
        objectContext.CommandTimeout = 1 * 60; // value in seconds
    }
}
沒落の蓅哖 2024-11-20 07:16:59

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

this.context.Database.CommandTimeout = 180;

If you are using DbContext and EF v6+, alternatively you can use:

this.context.Database.CommandTimeout = 180;
梦里泪两行 2024-11-20 07:16:59

如果您像我一样使用实体框架,您应该在启动类上定义超时,如下所示:

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

If you are using Entity Framework like me, you should define Time out on Startup class as follows:

 services.AddDbContext<ApplicationDbContext>(
   options => options.UseSqlServer(
     Configuration.GetConnectionString("DefaultConnection"), 
     a => a.CommandTimeout(180)));
晒暮凉 2024-11-20 07:16:59

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

int? prevto = uow.Context.Database.CommandTimeout;
uow.Context.Database.CommandTimeout = 900;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) {
...
}

在函数结束时,我将命令超时设置回 prevto 中的先前值。

使用 EF6

Usually I handle my operations within a transaction. As I've experienced, it is not enough to set the context command timeout, but the transaction needs a constructor with a timeout parameter. I had to set both time out values for it to work properly.

int? prevto = uow.Context.Database.CommandTimeout;
uow.Context.Database.CommandTimeout = 900;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) {
...
}

At the end of the function I set back the command timeout to the previous value in prevto.

Using EF6

如痴如狂 2024-11-20 07:16:59

我知道这是一个非常古老的线程正在运行,但 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;
    }
}

I know this is very old thread running, but still EF has not fixed this. For people using auto-generated DbContext can use the following code to set the timeout manually.

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;
    }
}
剧终人散尽 2024-11-20 07:16:59

在 .NET Core 中,使用以下语法将超时从默认的 30 秒更改为 90 秒:

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        this.Database.SetCommandTimeout(90); // <-- 90 seconds
    }
}

In .NET Core use the following syntax to change the timeout from the default 30 seconds to 90 seconds:

public class DataContext : DbContext
{
    public DataContext(DbContextOptions<DataContext> options) : base(options)
    {
        this.Database.SetCommandTimeout(90); // <-- 90 seconds
    }
}
终弃我 2024-11-20 07:16:59

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

那么我们开始吧:

如果您使用 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 Profiler 并检查 Entity 框架生成的 Select 语句。 ……

This is what I've fund out. Maybe it will help to someone:

So here we go:

If You use LINQ with EF looking for some exact elements contained in the list like this:

await context.MyObject1.Include("MyObject2").Where(t => IdList.Contains(t.MyObjectId)).ToListAsync();

everything is going fine until IdList contains more than one Id.

The “timeout” problem comes out if the list contains just one Id. To resolve the issue use if condition to check number of ids in IdList.

Example:

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();
}

Explanation:

Simply try to use Sql Profiler and check the Select statement generated by Entity frameeork. …

峩卟喜欢 2024-11-20 07:16:59

对于实体框架 6,我使用此注释并且工作正常。

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

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

CommandTimeout参数是一个可以为空的整数,用于设置超时
值为秒,如果设置 null 或不设置它将使用默认值
您使用的提供商的价值。

For Entity framework 6 I use this annotation and works fine.

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

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

The CommandTimeout parameter is a nullable integer that set timeout
values as seconds, if you set null or don't set it will use default
value of provider you use.

寂寞花火° 2024-11-20 07:16:59

将以下内容添加到我的存储过程中,解决了我的超时错误:

SET NOCOUNT ON;
SET ARITHABORT ON;

Adding the following to my stored procedure, solved the time out error by me:

SET NOCOUNT ON;
SET ARITHABORT ON;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文