2012-07-16 2 views
1

IoC 프레임 워크로 autofac 사용.
내 응용 프로그램을 시작할 때 내 DbContext 인스턴스를 설정할 수 있기를 원합니다.Entity Framework + Autofac - 저장시 임의 오류

내 ASP.NET MVC 3 프로젝트에서 DbContext 인스턴스를 Global.asax (PerLifetimeScope)에 등록합니다. 그러나 한 번에 여러 브라우저 (또는 여러 탭)에서 내 사이트를 실행하면 가끔으로 변경 사항을 데이터베이스에 다시 저장하려고하면 Object reference not set to an instance of an object. 또는 New transaction is not allowed because there are other threads running in the session이 표시됩니다. 또한 ExecuteReader requires an open and available Connection. The connection's current state: Broken. 때로는 데이터베이스에서 데이터를 읽고 싶습니다.

오류가 무작위로 팝업되는 것처럼 보입니다. 내 문맥의 수명 범위와 관련이 있다고 생각됩니다. 여기에 내 DbContext가 재정의 SaveChange 메서드입니다. 난 그냥 모든 작품을 좋아 브라우저에서 내 사이트의 하나 개의 탭이 열려있는 경우

builder.Register(c => new MyContext("SomeConnectionString")) 
       .InstancePerLifetimeScope(); 

: 여기

public class MyContext : DbContext 
{ 
    public override int SaveChanges() 
    { 
     var result = base.SaveChanges(); // Exception here 
    } 
} 

내가 내 컨텍스트를 등록하는 방법입니다.
또한 Ajax를 사용하여 컨트롤러 메소드를 호출하여 내 웹 사이트에서 5 ~ 10 초마다 db와 CRUD 작업을 수행 할 수 있습니다. New transaction is not allowed because there are other threads running in the session에 대한

스택 트레이스 : Object reference not set to an instance of an object.에 대한

at System.Data.EntityClient.EntityConnection.BeginDbTransaction(IsolationLevel isolationLevel) 
at System.Data.EntityClient.EntityConnection.BeginTransaction() 
at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) 
at System.Data.Entity.Internal.InternalContext.SaveChanges() 
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
at System.Data.Entity.DbContext.SaveChanges() 
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs 

스택 트레이스는 :

at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries) 
at System.Data.Objects.ObjectStateManager.DetectChanges() 
at System.Data.Entity.Internal.InternalContext.DetectChanges(Boolean force) 
at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate) 
at System.Data.Entity.Internal.InternalContext.GetStateEntries() 
at System.Data.Entity.Infrastructure.DbChangeTracker.Entries() 
at System.Data.Entity.DbContext.GetValidationErrors() 
at System.Data.Entity.Internal.InternalContext.SaveChanges() 
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
at System.Data.Entity.DbContext.SaveChanges() 
at MyProject.Data.MyContext.SaveChanges() in D:\Test.cs at 
+0

이 정보가 도움이 되나요? http://stackoverflow.com/questions/6237280/new-transaction-is-not-allowed-because-there-are-other-threads-running-in-the-se – Boomer

+0

제 이해는'InstancePerLifetimeScope'가 컨텍스트 생성을 처리해야합니다./각 HttpRequest에 대해 별도로 처리해야합니다. 그렇지 않다면 내 컨텍스트에 대한 사용자 정의 평생 범위 관리자를 작성하는 참조가 있습니까? – Kamyar

+0

나는이 문제도 잘 알고있다. –

답변

1

등록 MyContext 괜찮아 보인다. MyContext을 사용하는 다른 서비스가 싱글 톤으로 등록되고 스레드간에 공유 될 수 있습니까?

+0

그런 생각은하지 마라. 컨텍스트에 대한 액세스 권한이있는 싱글 톤에 대해 옳았습니다.하지만이를 제거한 후에도 여전히 이상한 컨텍스트 오류가 표시됩니다. 나는 더 많이 파헤 치려고 노력할 것이다. – Kamyar

1

Autofac을 사용하여 DbContext를 확인하는 동안 DbContext와 관련된 산발적 인 오류가 발생했습니다.

{System.Data.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. 
etc. 

{System.NullReferenceException: Object reference not set to an instance of an object. 
at System.Data.Objects.ObjectStateManager.DetectConflicts(IList`1 entries) 
etc. 

나는 내 코드에서 다음과 같은 클래스를 발견했다. 종속성 해결은 싱글 톤 내부의 정적 메서드 내에서 발생했습니다. 해결되는 개체에는 DbContext에 대한 종속성이 있습니다. 이 클래스를 구조 조정하여 더 이상 싱글 톤이되지 않도록하는 방법을 찾은 후에 추가 문제가 없었습니다.

아마도 비슷한 상황입니까? 시도 할 또 다른 사항은 DbContext InstancePerHttpRequest를 만드는 것일 수 있습니다. 이것이 문제인지 여부를 파악하는 데 도움이 될 수 있습니다.

public class Singleton 
{ 
    private static Singleton _instance = new Singleton(); 

    private Singleton() 
    { 

    } 

    public static void DoSomething<TSource>(TSource source) where TSource : ISource 
    { 
     var items = DependencyResolver.Current.Resolve<IEnumerable<IDbContextConsumer<TSource>>>(); 
     foreach (var item in items) 
     { 
      item.Execute(source); 
     } 
    } 
}