实体框架6及其问题SQLite的。 Any()查询失败但Contains()查询正在运行

时间:2016-02-03 06:44:40

标签: c# entity-framework sqlite

正在使用的工具:

  1. Entity Framework 6.0
  2. System.Data.Sqlite 1.0.98包[最新稳定版本]
  3. 问题: 假设下面给出的代码块:

    using(var dbContext = new DatabaseContext())
    {
    var hugeDataListObj= dbContext.Table1.Select(x=>x.Field1).ToList();
    //Do other Stuff here with hugeDataListObj.
    
    // The Below query will fail for Parser Stack overflow.
    var requiredResultObj = dbContext.Table2.Where(x=>hugeDataList.Any(y=> y==x.Field1)).ToList(); 
    
    
    //but The code given below works out well.
    var requiredResultObj = dbContext.Table2.Where(x=>hugeDataList.Contains(x.Field1)).ToList(); 
    
    /* Below given is the Detailed Exception.*/
     "InnerException": {
                "ExceptionType": "SQLiteException",
                "ExceptionMessage": "SQL logic error or missing database\r\nparser stack overflow",
                "StackTrace": "   at System.Data.SQLite.SQLite3.Prepare(SQLiteConnection cnn, String strSql, SQLiteStatement previous, UInt32 timeoutMS, String& strRemain)\r\n   at System.Data.SQLite.SQLiteCommand.BuildNextCommand()\r\n   at System.Data.SQLite.SQLiteCommand.GetStatement(Int32 index)\r\n   at System.Data.SQLite.SQLiteDataReader.NextResult()\r\n   at System.Data.SQLite.SQLiteDataReader..ctor(SQLiteCommand cmd, CommandBehavior behave)\r\n   at System.Data.SQLite.SQLiteCommand.ExecuteReader(CommandBehavior behavior)\r\n   at System.Data.SQLite.SQLiteCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)\r\n   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)\r\n   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)\r\n   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)\r\n   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)\r\n   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)",
                "Data": {},
                "ErrorCode": "-2147467259",
                "Source": "System.Data.SQLite",
                "HelpLink": null,
                "InnerException": null
            }
    }
    

    我查看过任何和包含的查询。两者都有巨大差异。 但那么我感到困惑的是Any()有性能问题吗?或者这是特定于案例的?

1 个答案:

答案 0 :(得分:3)

您的第一个语句var hugeDataListObj= dbContext.Table1.Select(x=>x.Field1).ToList();正在使用ToList(),将评估该查询并创建一个列表&lt;&gt;记忆中的原语。

您的第二个语句使用此列表来构建SQL语句。毫无疑问,您的EF提供商遇到了麻烦 - 它可能正在尝试构建和执行一个SQL语句,该语句包含IN ('a', 'b', 'c', 'd'...这样包含数千个值的子句。

这些查询都使用相同的dbContext。考虑在执行之前将查询组合成一个,这将导致连接在数据库中发生。

更好的是,因为这两个表之间存在概念链接,您可以在实体中创建导航属性,这使得围绕这些对象创建EF / Linq查询变得更加容易。有关如何执行此操作,请参阅EF文档。