완료하는 데 30 초 이상 걸리는 함수 가져 오기를 사용할 때 Entity Framework (EF)를 사용하여 시간 초과가 발생합니다. 다음을 시도했지만이 문제를 해결할 수 없었습니다.
여기에 제안 된대로 EDMX 파일이있는 프로젝트 Default Command Timeout=300000
의 App.Config 파일에 연결 문자열을 추가 했습니다 .
내 연결 문자열은 다음과 같습니다.
<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" />
내 저장소에서 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 : 시간 초과가 만료되었습니다. 작업이 완료되기 전에 시간 초과 기간이 경과했거나 서버가 응답하지 않습니다.
OK-나는이 일을했고 바보 일이 일어났습니다. 연결 문자열이 Default Command Timeout=300000
있고 CommandTimeout이 180으로 설정되었습니다 Default Command Timeout
. 연결 문자열에서 연결 문자열을 제거하면 작동했습니다. 따라서 정답은 컨텍스트 객체의 저장소에서 CommandTimeout을 수동으로 설정하는 것입니다.
this.context.CommandTimeout = 180;
연결 문자열에서 시간 초과 설정을 설정해도 영향을 미치지 않습니다.
답변
EF 연결 문자열 내에 기본 명령 시간 초과를 지정하는 알려진 버그가 있습니다.
http://bugs.mysql.com/bug.php?id=56806
연결 문자열에서 값을 제거하고 데이터 컨텍스트 오브젝트 자체에 설정하십시오. 연결 문자열에서 충돌하는 값을 제거하면 작동합니다.
엔티티 프레임 워크 코어 1.0 :
this.context.Database.SetCommandTimeout(180);
엔터티 프레임 워크 6 :
this.context.Database.CommandTimeout = 180;
엔터티 프레임 워크 5 :
((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180;
Entity Framework 4 이하 :
this.context.CommandTimeout = 180;
답변
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;
답변
일반적으로 트랜잭션 내에서 작업을 처리 합니다 . 내가 경험했듯이 컨텍스트 명령 시간 초과를 설정하는 것만으로는 충분하지 않지만 트랜잭션에는 시간 초과 매개 변수가있는 생성자가 필요합니다. 제대로 작동하려면 두 시간 제한 값을 설정해야했습니다.
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;
}
답변
나와 같은 Entity Framework를 사용하는 경우 다음과 같이 시작 클래스에서 시간 초과를 정의해야합니다.
services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(180)));
답변
이것이 내가 투자 한 것입니다. 어쩌면 누군가에게 도움이 될 것입니다.
그래서 우리는 간다 :
EF와 함께 LINQ를 사용하면 다음과 같이 목록에 포함 된 정확한 요소를 찾습니다.
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 frameeork에서 생성 한 Select 문을 확인하십시오. …