我有这个查询,我得到了这个函数的错误:

var accounts = from account in context.Accounts
               from guranteer in account.Gurantors
               select new AccountsReport
               {
                   CreditRegistryId = account.CreditRegistryId,
                   AccountNumber = account.AccountNo,
                   DateOpened = account.DateOpened,
               };

 return accounts.AsEnumerable()
                .Select((account, index) => new AccountsReport()
                    {
                        RecordNumber = FormattedRowNumber(account, index + 1),
                        CreditRegistryId = account.CreditRegistryId,
                        DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber),
                        AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)
                    })
                .OrderBy(c=>c.FormattedRecordNumber)
                .ThenByDescending(c => c.StateChangeDate);


public DateTime DateLastUpdated(long creditorRegistryId, string accountNo)
{
    return (from h in context.AccountHistory
            where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
            select h.LastUpdated).Max();
}

错误:

已经有一个打开的DataReader与此命令相关联,必须先关闭它。

更新:

添加堆栈跟踪:

InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first.]
   System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command) +5008639
   System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command) +23
   System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async) +144
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +87
   System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) +32
   System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) +141
   System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior) +12
   System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) +10
   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +443

[EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details.]
   System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior) +479
   System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute(ObjectContext context, ObjectParameterCollection parameterValues) +683
   System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +119
   System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +38
   System.Linq.Enumerable.Single(IEnumerable`1 source) +114
   System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__3(IEnumerable`1 sequence) +4
   System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +29
   System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +91
   System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +69
   System.Linq.Queryable.Max(IQueryable`1 source) +216
   CreditRegistry.Repositories.CreditRegistryRepository.DateLastUpdated(Int64 creditorRegistryId, String accountNo) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1497
   CreditRegistry.Repositories.CreditRegistryRepository.<AccountDetails>b__88(AccountsReport account, Int32 index) in D:\Freelance Work\SuperExpert\CreditRegistry\CreditRegistry\Repositories\CreditRegistryRepository.cs:1250
   System.Linq.<SelectIterator>d__7`2.MoveNext() +198
   System.Linq.Buffer`1..ctor(IEnumerable`1 source) +217
   System.Linq.<GetEnumerator>d__0.MoveNext() +96

当前回答

我在我的工具中使用web服务,这些服务获取存储过程。当越来越多的客户端工具获取web服务时,这个问题就出现了。我通过为这些函数指定Synchronized属性来修复存储过程。现在它工作良好,错误从未出现在我的工具。

 [MethodImpl(MethodImplOptions.Synchronized)]
 public static List<t> MyDBFunction(string parameter1)
  {
  }

此属性允许一次处理一个请求。这就解决了问题。

其他回答

我通过改变解决了这个问题 等待_accountSessionDataModel.SaveChangesAsync (); 来 _accountSessionDataModel.SaveChanges (); 在我的Repository类中。

 public async Task<Session> CreateSession()
    {
        var session = new Session();

        _accountSessionDataModel.Sessions.Add(session);
        await _accountSessionDataModel.SaveChangesAsync();
     }

改为:

 public Session CreateSession()
    {
        var session = new Session();

        _accountSessionDataModel.Sessions.Add(session);
        _accountSessionDataModel.SaveChanges();
     }

问题是我在创建会话(在代码中)后在前端更新了会话,但由于SaveChangesAsync是异步发生的,获取会话导致了这个错误,因为显然SaveChangesAsync操作还没有准备好。

顺便说一句……当SQL对象的(内部)数据映射出现问题时,也会发生这种情况。

例如……

我创建了一个SQL标量函数,意外返回一个VARCHAR…然后……使用它在VIEW中生成一个列。视图被正确映射到DbContext…所以Linq说的很好。然而,实体期望DateTime?VIEW返回String。

奇怪的是……

"已经有一个与此命令相关联的开放数据阅读器 必须先关闭"

很难弄明白……但在我修正了返回参数后…一切顺利

可以在return语句之前使用ToList()方法。

var accounts =
from account in context.Accounts
from guranteer in account.Gurantors

select new AccountsReport
{
    CreditRegistryId = account.CreditRegistryId,
    AccountNumber = account.AccountNo,
    DateOpened = account.DateOpened,
};

return accounts.AsEnumerable()
       .Select((account, index) => new AccountsReport()
       {
           RecordNumber = FormattedRowNumber(account, index + 1),
           CreditRegistryId = account.CreditRegistryId,
           DateLastUpdated = DateLastUpdated(account.CreditRegistryId, account.AccountNumber),
            AccountNumber = FormattedAccountNumber(account.AccountType, account.AccountNumber)
       })
       .OrderBy(c=>c.FormattedRecordNumber)
       .ThenByDescending(c => c.StateChangeDate)
       .ToList();


public DateTime DateLastUpdated(long creditorRegistryId, string accountNo)
{
    var dateReported = (from h in context.AccountHistory
                        where h.CreditorRegistryId == creditorRegistryId && h.AccountNo == accountNo
                        select h.LastUpdated).Max();
    return dateReported;
}

这个问题很可能是因为实体框架的“惰性加载”特性。通常,除非在初始获取期间明确要求,否则所有联接数据(存储在其他数据库表中的任何数据)只在需要时才会获取。在许多情况下,这是一件好事,因为它可以防止获取不必要的数据,从而提高查询性能(无连接)并节省带宽。

在问题中描述的情况下,执行初始获取,并在“选择”阶段请求缺少惰性加载数据,发出额外的查询,然后EF抱怨“打开DataReader”。

在已接受的回答中提出的解决方案将允许执行这些查询,实际上整个请求将成功。

但是,如果检查发送到数据库的请求,您将注意到多个请求—每个缺失(惰性加载)数据的附加请求。这可能是性能杀手。

更好的方法是告诉EF在初始查询期间预加载所有需要的惰性加载数据。这可以使用"Include"语句完成:

using System.Data.Entity;

query = query.Include(a => a.LazyLoadedProperty);

这样,将执行所有需要的连接,并将所有需要的数据作为单个查询返回。问题中描述的问题将被解决。

对我来说,那是我自己的虫子。当我应该使用SqlCommand.ExecuteNonQuery()时,我试图使用SqlCommand.executeReader()运行一个INSERT。它被打开而从未关闭,导致了错误。注意这个疏忽。