2017-10-09 3 views
0

다음과 같은 Entity Framework Core 1.1.1 사용으로 인해 예외가 발생하는 이유는 무엇입니까?루프에서 Entity Framework Core 호출이 InvalidOperationException을 throw하는 이유는 무엇입니까?

// Arrange. 
using(var context = new BasicContext()) 
{ 
    Author[] authors = new[] 
    { 
     new Author { Name = "Bob"}, 
     new Author { Name = "Fred" } 
    }; 
    context.Authors.AddRange(authors); 

    Book[] books = new[] 
    { 
     new Book { Title = "Book 1" }, 
     new Book { Title = "Book 2" } 
    }; 

    context.SaveChanges();    
} 

// Act. 
bool exception = false; 

using(var context = new BasicContext()) 
{ 
    foreach(Author a in context.Authors) 
    { 
     try 
     { 
     string title = context.Books.First().Title; 
     } 
     catch(Exception) 
     { 
     exception = true; 
     } 
    } 
} 

// Assert. 
Assert.False(exception); 

예외입니다 위해 Postgress (Npgsql)에 대한 엔티티 커넥터를 사용하여 제기 :

Npgsql.NpgsqlOperationInProgressException : A command is already in progress: SELECT "a"."AuthorId", "a"."Name" 
FROM "Authors" AS "a" 
Stack Trace: 
    at Npgsql.NpgsqlConnector.StartUserAction(ConnectorState newState, NpgsqlCommand command) 
    at Npgsql.NpgsqlCommand.<ExecuteDbDataReader>d__92.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 
    at System.Runtime.CompilerServices.ValueTaskAwaiter`1.GetResult() 
    at Npgsql.NpgsqlCommand.ExecuteDbDataReader(CommandBehavior behavior) 
    at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.Execute(IRelationalConnection connection, String execute 
Method, IReadOnlyDictionary`2 parameterValues, Boolean closeConnection) 
    at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteReader(IRelationalConnection connection, IReadOnlyDictionary`2 parameterValues) 
    at Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable.Enumerator.BufferlessMoveNext(Boolean buffer) 
    at Microsoft.EntityFrameworkCore.Query.QueryMethodProvider.<_ShapedQuery>d__3`1.MoveNext() 
    at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) 
    at lambda_method(Closure , QueryContext) 
    at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass20_0`1.<CompileQueryCore>b__0(QueryContext qc 
) 
    at System.Linq.Queryable.First[TSource](IQueryable`1 source) 
    at BasicTesting.BasicTests.TestEnumerate() in C:\_Home\Development\Workspaces\DotnetCoreTesting\EntityTesting3\BasicTesting\BasicTests.cs:line 147If 'foreach(Author a in context.Authors)' is replaced with 'foreach(Author a in context.Authors.ToArray())' no exception occurs. 

이 나는 ​​일이 무엇을 기대하지 않습니다.

foreach 루프에 도달하면 context.Authors를 평가해야합니다. 서브 시퀀스 'Books.First'표현식이 다른 데이터베이스 연산을 초래할 때 진행중인 기존 연산이 없어야합니다.

+0

가능한 중복 https://stackoverflow.com/questions/6062192/there-is-already-an-open-datareader (이 명령과 관련이있는) – Igor

+0

두 개의 고유 한 명령을 사용할 때 [오류 "이미이 명령과 관련된 열려있는 DataReader가 있으므로 먼저 닫아야합니다"] 가능한 복제본 (https :///postquestions/18475195) – Igor

+0

'postgressql'에 MARS (Multiple Active Result Sets)를 활성화하는 옵션이 있는지는 잘 모르겠지만 문제도 해결할 수 있습니다. – Igor

답변

1

일부 제공 업체는 여러 명의 독자가 읽는 것을 지원하지 않습니다. 이를 피하는 가장 좋은 방법은 책을 조회하기 전에 모든 저자를 읽는 것입니다. .ToList()을 추가하는 것이 가장 간단한 방법입니다 (꼭 필요한 것은 아닙니다).

foreach (Author a in context.Authors.ToList()) 
{ 
    // ... context.Books ... 
} 
([이미 먼저 닫아야이 명령과 관련된 열린 DataReader가있다]의