我很困惑为什么会这样。我是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查询。没意识到我需要那样做。我感谢所有的帮助!
感谢, 贾斯汀
答案 0 :(得分:2)
第一个查询是使用Linq-To-Entities。 Linq-To-Entities方法构建一个表达式树,在枚举时将其转换为sql。如果你包含一些它无法转换为sql的东西,你会得到一个例外。 ToString()
就是一个例子。 LINQ to Entities does not recognize the method '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的问题