C# Repository-打开与此命令关联的DataReader,必须先关闭该命令
我有一个用实体框架用MVC编写的游戏的启动方法,它已经覆盖了存储库和工作单元:C# Repository-打开与此命令关联的DataReader,必须先关闭该命令,c#,entity-framework,repository,unit-of-work,C#,Entity Framework,Repository,Unit Of Work,我有一个用实体框架用MVC编写的游戏的启动方法,它已经覆盖了存储库和工作单元: public Team StartTeam(Message message, out string result) { try { var player = GetPlayer(message); if (player.StatusId == (int)Status.Playing) {
public Team StartTeam(Message message, out string result)
{
try
{
var player = GetPlayer(message);
if (player.StatusId == (int)Status.Playing)
{
result = Mesages.CantStartGameDuringAnotherGame;
return null;
}
var team = Uow.TeamContext.FindBy(q => q.Name == message.Text).FirstOrDefault();
if (team == null)
{
result = Mesages.UnexpectedError;
return null;
}
var members = Uow.MembershipContext.FindBy(q => q.TeamId == team.Id);
var players = new List<Player>();
foreach (var member in members.Where(q => q.PlayerId != player.Id))
{
var pl = Uow.PlayerContext.GetSingle(member.PlayerId);
if (player.StatusId == (int)Status.Active)
players.Add(pl);
}
players.Add(player);
player.StatusId = (int)Status.Active;
if (players.Count < 2)
{
result = Mesages.NotEnoughPlayers;
return null;
}
var race = new Race()
{
TeamId = team.Id,
PlayDate = DateTime.Now
};
race = Uow.RaceContext.Add(race);
Uow.Save();
team.CurrentRaceId = race.Id;
foreach (var playr in players)
{
playr.StatusId =
members.First(q => q.PlayerId == playr.Id).StatusId
= (int)Status.Playing;
playr.CurrentTeamId = team.Id;
}
result = Mesages.TeamStartedSuccessfuly;
player.StatusId = (int)Status.Playing;
return team;
}
catch (Exception ex)
{
SaveException(ex);
return null;
}
}
这是完整的堆栈跟踪:
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.
at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
--- End of inner exception stack trace ---
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
at EsmFamilWebHoook.Models.PlayerRepository.GetSingle(Int32 playerId)
at EsmFamilWebHoook.DatabaseService.StartTeam(Message message, String& result)
System.Data.Entity.Core.EntityCommandExecutionException:执行命令定义时出错。有关详细信息,请参见内部异常。-->System.InvalidOperationException:已存在与此命令关联的打开的DataReader,必须先关闭该DataReader。
位于System.Data.SqlClient.SqlInternalConnectionDS.ValidateConnectionForExecute(SqlCommand)
位于System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(字符串方法,SqlCommand)
位于System.Data.SqlClient.SqlCommand.ValidateCommand(字符串方法,布尔异步)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法、TaskCompletionSource`1 completion、Int32超时、Task&Task、Boolean asyncWrite)
位于System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior RunBehavior、Boolean returnStream、String方法)
位于System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior,String方法)
位于System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior)
位于System.Data.Common.DbCommand.ExecuteReader(CommandBehavior)
在System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.b_uÈc(DbCommand t,DbCommandInterceptionContext`1c)
在System.Data.Entity.Infrastructure.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget目标,Func`3操作,TInterceptionContext拦截Context,操作`3执行,操作`3执行)
位于System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand命令,DbCommandInterceptionContext interceptionContext)
位于System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior)
位于System.Data.Common.DbCommand.ExecuteReader(CommandBehavior)
位于System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStorommands(EntityCommand EntityCommand,CommandBehavior)
---内部异常堆栈跟踪的结束---
位于System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStorommands(EntityCommand EntityCommand,CommandBehavior)
位于System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext上下文,ObjectParameterCollection parameterValues)
在System.Data.Entity.Core.Objects.ObjectQuery`1.c_u DisplayClass7.b__u6()
在System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 Func,IDBEcutionStrategy executionStrategy,Boolean startLocalTransaction,Boolean releaseConnectionOnSuccess)
在System.Data.Entity.Core.Objects.ObjectQuery`1.c__DisplayClass7.b__5()中
在System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1操作)中
位于System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(可为null`1 forMergeOption)
位于System.Data.Entity.Core.Objects.ObjectQuery`1.b_u 0()
位于System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
位于System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1源)
位于System.Data.Entity.Core.Objects.Elink.ObjectQueryProvider.b__1[TResult](IEnumerable`1序列)
位于System.Data.Entity.Core.Objects.Elink.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1查询,表达式queryRoot)
位于System.Data.Entity.Core.Objects.Elink.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](表达式)
在System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](表达式)处
位于System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1源,表达式`1谓词)
在EsmFamilyWebhoook.Models.PlayerRepository.GetSingle(Int32 playerId)上
在EsmFamilyWebhoook.DatabaseService.StartTeam(消息、字符串和结果)
发生了什么事?
我看到了,但没有帮助我 可能是您的查询:
var pl = Uow.PlayerContext.GetSingle(member.PlayerId);
放置在foreach中,该foreach迭代另一个查询的结果(但此查询可能仍然处于活动状态-可能只是读取第一批行,或者正在进行延迟加载):
尝试首先使用.ToArray()强制将第一个查询的结果完全加载到内存中,例如:
foreach (var member in Uow.MembershipContext.FindBy(q => q.TeamId == team.Id).Where(q => q.PlayerId != player.Id).ToArray())
通常一次可以有1个查询处于活动状态。可能是您的查询:
var pl = Uow.PlayerContext.GetSingle(member.PlayerId);
放置在foreach中,该foreach迭代另一个查询的结果(但此查询可能仍然处于活动状态-可能只是读取第一批行,或者正在进行延迟加载):
尝试首先使用.ToArray()强制将第一个查询的结果完全加载到内存中,例如:
foreach (var member in Uow.MembershipContext.FindBy(q => q.TeamId == team.Id).Where(q => q.PlayerId != player.Id).ToArray())
通常,一次可以有1个查询处于活动状态