C# 实体框架超时
我使用实体框架(EF)在使用需要30秒以上才能完成的函数导入时超时。我尝试了以下操作,但未能解决此问题: 我将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<
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
}