1

我很困惑为什么会这样。我是 LINQ 的新手,所以我显然在这里遗漏了一些东西,这可能很容易。我已经查找了有关该主题的帮助,但我真的不知道该问什么,所以我没有找到任何真正解决我问题的答案。

这不起作用

EntityCommandExecutionException它在FirstOrDefault方法执行时抛出一个。

var query = from band in context.BandsEntitySet
            where band.ID == 12345
            select band;

foreach (var item in query)
{
    string venueName = item.VenueName;

    var venue = context.VenueEntitySet.FirstOrDefault(r => r.Venue.Equals(venueName));

    if(venue != null)
    {
        Debug.WriteLine(item.Name + " is playing in " + venueName + " on the " + item.PlayDate);
        Debug.WriteLine("The address of " + venueName + " is " + venue.Address);
    }
}

这有效

var query = from band in context.BandsEntitySet
                    where band.ID == 12345
                    select band;

var bandList = query.toList();

foreach (var item in bandList)
{
    string venueName = item.VenueName;

    var venue = context.VenueEntitySet.FirstOrDefault(r => r.Venue.Equals(venueName));

    if(venue != null)
    {
        Debug.WriteLine(item.Name + " is playing in " + venueName + " on the " + item.PlayDate);
        Debug.WriteLine("The address of " + venueName + " is " + venue.Address);
    }
}

我的问题很简单:为什么会抛出异常?为什么从查询创建列表允许我使用该FirstOrDefault方法?

异常消息: A first chance exception of type 'System.Data.EntityCommandExecutionException' occurred in System.Data.Entity.dll

我想我假设查询是一个列表是错误的?那么究竟是什么呢?

这是堆栈跟踪

A first chance exception of type 'System.Data.EntityCommandExecutionException' occurred in System.Data.Entity.dll
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
   at System.Data.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
   at System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator()
   at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
   at System.Data.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1[TResult](IEnumerable`1 sequence)
   at System.Data.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[S](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 BandManagementProject.AutoUpdate.Dev() in c:\BandManagementProject\AutoUpdate.cs:line 99
   at BandManagementProject.AutoUpdate.Main(String[] args) in c:\BandManagementProject\AutoUpdate.cs:line 41

内部异常

MySql.Data.MySqlClient.MySqlException (0x80004005): There is already an open DataReader associated with this Connection which must be closed first.
   at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
   at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex)
   at MySql.Data.MySqlClient.MySqlCommand.Throw(Exception ex)
   at MySql.Data.MySqlClient.MySqlCommand.CheckState()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.Entity.EFMySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)

结论 在执行其他查询之前,我没有关闭我的 LINQ 查询。没有意识到我需要这样做。我感谢所有的帮助!

谢谢,贾斯汀

4

1 回答 1

2

第一个查询是使用 Linq-To-Entities。Linq-To-Entities 方法构建一个表达式树,在您枚举时将其转换为 sql。如果您包含无法转换为 sql 的内容,则会出现异常。 ToString()是一个例子。 LINQ to Entities 无法识别方法“System.String ToString()”

调用ToList()使枚举发生。于是sql运行起来,不包含任何不能翻译的东西,数据被移到内存中。现在您正在使用 Linq-To-Objects,并且可以识别标准 C# 方法调用

尝试这个:

var venue = context.VenueEntitySet.FirstOrDefault(r => r.Venue == venueName))

编辑好的,我们知道现在这不是问题 - 但要考虑的另一个想法是在一次调用数据库中获取数据。像这样的东西:

        var query = from band in context.BandsEntitySet
                    //not sure the join makes sense. How come every band has a VenueName?
                    //join venue in context.VenueEntitySet 
                    //on band.VenueName equals venue.Name
                    //surely there should be a navigation property
                    from venue in band.Venues //using a navigation property
                    where band.ID == 12345
                    select new { 
                                   BandName = band.Name, 
                                   VenueName = venue.Name, 
                                   PlayDate = venue.PlayDate, 
                                   Address = venue.Address 
                               };

        foreach (var item in query)
        {                
            Debug.WriteLine(item.BandName + " is playing in " 
                           + item.VenueName + " on the " + item.PlayDate);
            Debug.WriteLine("The address of " + item.VenueName + " is " + item.Address);

        }

这也应该避免多个打开的 DataReader 的问题

于 2013-11-11T15:23:35.397 回答