【问题标题】:MySQL - Where Issues with Entity FrameworkMySQL - 实体框架的问题
【发布时间】:2017-07-03 13:43:57
【问题描述】:

此查询有效。

string value = null;
var temp1 = (from d in db.Device
             where                                 
                (value == null ? true : d.Status == 1)
              select d).ToList();

但是这个查询不起作用。

string value = null;
var temp1 = (from d in db.Device
             where                                 
                (value == null ? true : d.Status == 1)
              select d).OrderBy(i => i.Title).ToList();

Device 模型具有 StatusTitle 属性。

错误:Object reference not set to an instance of an object.

MySql.Data 版本:6.9.9

Connector/Net: 6.9.9

MySql.Data.Entity.EF6

只需添加 orderby 并得到错误。你能告诉我为什么吗?

堆栈跟踪:

  at MySql.Data.Entity.CaseFragment.Accept(SqlFragmentVisitor visitor) at MySql.Data.Entity.BinaryFragment.Accept(SqlFragmentVisitor visitor) at MySql.Data.Entity.SqlGenerator.FuseSelectWithInnerSelect(SelectStatement outer, SelectStatement inner)    at MySql.Data.Entity.SqlGenerator.TryFusingSelect(InputFragment f)    at MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type)    at MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type)    at MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression)    at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)    at MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree)    at MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)    at System.Data.Entity.Core.Common.DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)    at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)    at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)    at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)    at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)    at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)    at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)    at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)    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.Infrastructure.DefaultExecutionStrategy.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.Collections.Generic.List`1..ctor(IEnumerable`1 collection)    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)

【问题讨论】:

  • 听起来像一个错误。异常堆栈跟踪如何?
  • 是否可以在执行查询后进行排序?这意味着 .ToList().OrderBy()?如果可行,则可能是查询生成问题。
  • 你愿意使用 lambda 表达式吗?
  • @IvanStoev 添加了堆栈跟踪。冷,你再检查一遍?
  • 嗯,这不是你的代码,而是一些 MySQL 连接器内部表达式访问者代码,所以肯定是 MySQL 连接器错误。

标签: c# mysql .net entity-framework


【解决方案1】:

根据堆栈跟踪,这是处理 ? : 运算符部分 (CaseFragment) 时的 MySQL 连接器错误。

通过消除? : 构造,我们找到了解决方法

(value == null ? true : d.Status == 1)

与等价物

(value == null || d.Status == 1)

【讨论】:

  • 您可以重写查询并完全消除value == null,因为它只是一个本地标志。查询中不使用它
  • @PanagiotisKanavos 我知道这一点。我认为这是 OP 的一个简化(而且选择得不是很好)的例子。我也更喜欢有条件的Where 方法,但它并不总是适用,而且还会破坏查询语法的自然流程。在one point,我试图通过后处理查询表达式树来充分利用两者,但还没有时间完成这个想法:)
【解决方案2】:

您似乎正在尝试将包罗万象的查询重写为 LINQ。您根本不需要使用 LINQ 编写包罗万象的查询,如果您不想要它,您可以简单地忽略该条件,例如:

string value=someOptionalParameter;
var query = (value==null)? db.Device : db.Where(d=>d.Status == 1);    
var temp1 =  query.OrderBy(d=>d.Title).ToList();

在这种情况下,根本不使用value。它只是用作旗帜。如果您确实想要使用它,例如选择通过Category 字段进行过滤,您可以在 where 子句中以相同的方式使用它:

string value=someOptionalParameter;
var query = (value==null)? db.Device : db.Where(d=>d.Category == value);    
var temp1 =  query.OrderBy(d=>d.Title).ToList();

一般来说,您可以一点一点地“构建”查询。 IQueryable&lt; T&gt; 直到您尝试枚举它和/或将其转换为列表、数组等时才会转换为 SQL。您可以从用户的选项动态创建查询,如下所示:

var query = dbContext.MyEntity;
if (someField != null)
{
    query = query.Where(d=>d.SomeField = someField);
}

if (someOtherField != null)
{
    query = query.Where(d=>d.SomeOtherField = someField);
}

if (mustOrder != null)
{
    query = query.OrderBy(d=>d.OrderField);
}

//Execute the final query
return query.ToList();

【讨论】:

  • 这种方式会更好。谢谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-10
  • 2011-03-09
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
相关资源
最近更新 更多