【问题标题】:Linq, EF4, Filter data after Linq queryLinq,EF4,Linq查询后过滤数据
【发布时间】:2012-07-12 21:47:10
【问题描述】:

我想过滤 Linq 查询后的结果。

并使其成为 List() 或 Array()。

这是我的代码,

//for test, filter is always true
bool filter = true;

OrdersRepository ordersRepository = new OrdersRepository();

var productInQuery = ordersRepository.ProductIn;
var productOutQuery = ordersRepository.ProductOut;
var productQuery = ordersRepository.Product;
var orderInfoQuery = ordersRepository.OrderInfo;

var result = (from p in productInQuery
      join o in orderInfoQuery on p.refNo equals o.refNo
      join x in productQuery on p.productNo equals x.no
      join t in productOutQuery on p.no equals t.productInNo into productIn
      from t in productIn.DefaultIfEmpty()
      orderby o.processDate descending
      select new reportModel
      {
          yourRef = o.yourRefNo,
          modelNo = x.modelNo,
          mfgNo = p.mfgNo,
          serialNo = p.serialNo,
          poNo = p.poNo,
          lbs =  p.lbs,
          width = p.width,
          height = p.height,
          depth = p.depth,
          qty = p.qty,
          dateIn = o.processDate,
          dateOut = (from m in orderInfoQuery where m.refNo == t.refNo select m.processDate).FirstOrDefault(),
          etaDate = (from w in orderInfoQuery where w.refNo == t.refNo select w.eta).FirstOrDefault()
      });

// Filter one more time
if (filter)
{
    List<reportModel> a = (from q in result
         where q.etaDate >= new DateTime(2012, 5, 20)
         select q).ToList();

    //var a = result.Where(q => q.etaDate >= new DateTime(2012, 5, 20)).ToList(); //I tried this too, but it does not work either.
}
else
{
    var a = result.ToList();
}

运行上述代码时,出现错误信息。

Specified method is not supported.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.NotSupportedException: Specified method is not supported.

Source Error: 


Line 64:                  */
Line 65: 
Line 66:                 var a = result.Where(q => q.etaDate >= new DateTime(2012, 5, 20)).ToList();
Line 67:             }
Line 68:             else

Source File: WebUI\Controllers\TestController.cs    Line: 66 

Stack Trace: 


[NotSupportedException: Specified method is not supported.]
   MySql.Data.Entity.SqlGenerator.Visit(DbApplyExpression expression) +28
   System.Data.Common.CommandTrees.DbApplyExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type) +35
   MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type) +21
   MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression) +38
   System.Data.Common.CommandTrees.DbProjectExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type) +35
   MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type) +21
   MySql.Data.Entity.SelectGenerator.Visit(DbFilterExpression expression) +37
   System.Data.Common.CommandTrees.DbFilterExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type) +35
   MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type) +21
   MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression) +38
   System.Data.Common.CommandTrees.DbProjectExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type) +35
   MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type) +21
   MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression) +38
   System.Data.Common.CommandTrees.DbProjectExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type) +35
   MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type) +21
   MySql.Data.Entity.SelectGenerator.Visit(DbSortExpression expression) +63
   System.Data.Common.CommandTrees.DbSortExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type) +35
   MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type) +21
   MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression) +38
   System.Data.Common.CommandTrees.DbProjectExpression.Accept(DbExpressionVisitor`1 visitor) +23
   MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree) +60
   MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree) +334
   System.Data.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree) +147
   System.Data.EntityClient.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree) +526

[EntityCommandCompilationException: An error occurred while preparing the command definition. See the inner exception for details.]
   System.Data.EntityClient.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree) +1329
   System.Data.EntityClient.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree) +97
   System.Data.EntityClient.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree) +198
   System.Data.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree) +147
   System.Data.Objects.Internal.ObjectQueryExecutionPlan.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Span span, ReadOnlyCollection`1 compiledQueryParameters) +397
   System.Data.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) +696
   System.Data.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +149
   System.Data.Objects.ObjectQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +44
   System.Data.Entity.Internal.Linq.InternalQuery`1.GetEnumerator() +40
   System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator() +40
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +315
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
   BseWms.WebUI.Controllers.TestController.dateTest() in C:\Users\mark\Documents\Visual Studio 2010\Projects\BseWms\BseWms.WebUI\Controllers\TestController.cs:66
   lambda_method(Closure , ControllerBase , Object[] ) +62
   System.Web.Mvc.<>c__DisplayClass1.<WrapVoidAction>b__0(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
   System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +208
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
   System.Web.Mvc.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() +55
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +263
   System.Web.Mvc.<>c__DisplayClass17.<InvokeActionMethodWithFilters>b__14() +19
   System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +191
   System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
   System.Web.Mvc.Controller.ExecuteCore() +116
   System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
   System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
   System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
   System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
   System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
   System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
   System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
   System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
   System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
   System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8970349
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184

还有 reportModel 类。

public class reportModel
{
    public string yourRef {get; set;}
    public string modelNo {get; set;}
    public string mfgNo {get; set;}
    public string serialNo {get; set;}
    public string poNo {get; set;}
    public Nullable<float> lbs { get; set; }
    public Nullable<float> width { get; set; }
    public Nullable<float> height { get; set; }
    public Nullable<float> depth { get; set; }
    public int qty {get; set;}
    public Nullable<DateTime> dateIn { get; set; }
    public Nullable<DateTime> dateOut { get; set; }
    public Nullable<DateTime> etaDate { get; set; }
}

这段代码有什么问题? @.@;

谁知道,请指教。

谢谢

[编辑]

@Tyrsius

我按照您的建议尝试过,但出现了同样的错误。

var thedate = new DateTime(2012, 5, 20);
List<reportModel> a = (from q in result
                       where q.etaDate >= thedate
                       select q).ToList();

【问题讨论】:

  • InnerException 中有什么特别的东西可以给我们一个线索吗?

标签: asp.net asp.net-mvc-3 linq entity-framework


【解决方案1】:

假设结果执行良好,您可以像这样过滤查询:

if(filter)
{
    var dateFilter = new DateTime(2012, 5, 20);
    result = result.Where(x => x.etaDate >= dateFilter);
}

return result.ToList(); //or .ToArray() 

我建议你在结果执行后放置一个断点,看看你是否有正确的reportModel。 result 已经被转换为 IQueryable,是否有特殊原因要将其转换为 List?

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    这里有点

    List<reportModel> a = (from q in result 
        where q.etaDate >= new DateTime(2012, 5, 20) select q).ToList();
    

    是非法的,因为 EF 需要把它翻译成 SQL,而且你不能像 new Datetime() 这样传入对象构造函数。解决方案很简单:在尝试在查询中使用对象之前构造对象

    var date = new DateTime(2012, 5, 20);
    List<reportModel> a = (from q in result 
        where q.etaDate >= date select q).ToList();
    

    【讨论】:

    • 我按照您的建议进行了尝试,但仍然存在相同的错误。我将结果视图添加到我的问题中,请您再次查看我的问题吗?
    • @Expertwannabe 嗯。对结果的原始调用被推迟,所以它可能会在DefaultIfEmpty 上跳闸,我认为 EF 不支持。我猜你看到有人试图用它做一个外部连接?如果是这样,请参阅此问题:stackoverflow.com/questions/1770586/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多