2017-10-09 106 views
0

爲什麼以下使用Entity Framework Core 1.1.1會導致異常?使用Postgress(Npgsql的)實體連接器爲什麼實體框架核心調用循環拋出InvalidOperationException?

// 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); 

異常升高是:

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

的[已經有與此命令相關的開放的DataReader,必須先關閉](可能的複製https://stackoverflow.com/questions/6062192/there-is-already-an-open-datareader - 與這個命令相關的必須是-c) – Igor

+0

可能有[錯誤「當使用2個不同的命令時,已經有一個與此命令關聯的打開的DataReader,它必須先關閉」)(https:/ /stackoverflow.com/questions/18475195) – Igor

+0

不確定'postgressql'是否可以啓用MARS(多活動結果集),但是*可以*修復你的問題。 – Igor

回答

1

某些供應商不支持擁有多個開放閱讀器。避免這種情況的最好方法是在查詢書籍之前閱讀所有作者。添加.ToList()是最簡單的方法(但不一定是最好的)。

foreach (Author a in context.Authors.ToList()) 
{ 
    // ... context.Books ... 
}