简体   繁体   English

什么是 function 评估需要所有线程运行?

[英]What is the function evaluation requires all threads to run?

I just made a table Cust and in Ado.net and created an dbEntity to use LINQ我刚刚制作了一张桌子 Cust 和 Ado.net 并创建了一个 dbEntity 来使用 LINQ

But I am getting this error and I am not able to fetch the records.但是我收到了这个错误,我无法获取记录。

  protected void Page_Load(object sender, EventArgs e)
    {

        SSEntities db = new SSEntities();


        var a = from tb in db.Custs
                select tb;

    }

ConnectionString --连接字符串——

    <add name="SSEntities" connectionString="metadata=res://*/DbModel.csdl|res://*/DbModel.ssdl|res://*/DbModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=XYZ\SQLEXPRESS;initial catalog=SS;persist security info=True;user id=sa;password=La123;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />

Error- function evaluation requires all threads to run错误 - function 评估需要所有线程运行

But this works但这有效

     protected void Page_Load(object sender, EventArgs e)
    {

        SSEntities db = new SSEntities();


        var a = db.Custs.FirstOrDefault();

    }

You'll have to be aware about the deferred execution that LINQ uses.您必须了解 LINQ 使用的延迟执行。

Assuming db.Custs is an object that implements IQueryable<Cust> or something similar.假设db.Custs是一个 object 实现IQueryable<Cust>或类似的东西。

If you check the type of a in your first example, you'll see that it is an IQueryable<Cust> .如果您在第一个示例中检查a的类型,您会看到它是一个IQueryable<Cust> The one in your 2nd example is a Cust .第二个示例中的一个是Cust

If you examine the LINQ methods, you'll notice that there are two groups of them: the ones that return IEnumerable<TResult> (or IQueryable<TResult> ) and the ones that don't.如果您检查 LINQ 方法,您会注意到它们有两组:返回IEnumerable<TResult> (或IQueryable<TResult> )的一组和不返回的一组。

Select, Join, GroupBy are examples of the first group. Select, Join, GroupBy是第一组的示例。 They don't execute the query.他们不执行查询。 They don't represent fetched data, they represent the potential to select data and to enumerate it.它们不代表获取的数据,它们代表select 数据的潜力并枚举它。

As long as you only concatenate functions from this group.只要您只连接该组中的函数。 the source of your data is not queried.不查询您的数据来源。 This source is quite often a database, but it can be anything enumerable, CSV-file reader, JSON-files, information from the internet.这个来源通常是一个数据库,但它可以是任何可枚举的、CSV 文件阅读器、JSON 文件、来自互联网的信息。 In LINQ terms, we say that these methods use deferred execution.在 LINQ 术语中,我们说这些方法使用延迟执行。 You can find this term at every description of the method.您可以在该方法的每个描述中找到该术语。

Examples of methods from the second group are ToList, FirstOrDefault, Count, Any : the return is not an IQueryable<...> .第二组方法的示例是ToList, FirstOrDefault, Count, Any :返回不是IQueryable<...> Executing one of these methods will start enumerating the IEnumerable/IQueryable that is the input source: the first element will be fetched, and if there is one, and if needed for the method, other elements of the sequence will be fetched.执行其中一个方法将开始枚举作为输入源的 IEnumerable/IQueryable:将获取第一个元素,如果有,并且如果方法需要,将获取序列的其他元素。

Back to your question回到你的问题

Your first page-load will create the query.您的第一个页面加载将创建查询。 The potential to fetch the data from your database is created.创造了从数据库中获取数据的潜力。 Alas, you forgot to execute the query.唉,你忘了执行查询。 If you debug your program, and stop all threads at a breakpoint, and want to examine the value of a, you want to see the properties of object a .如果您调试程序,并在断点处停止所有线程,并希望检查 a 的值,您希望查看 object a的属性。 Alas, your debugger is willing to show you the results of simple properties, but contacting the database is too difficult for it.唉,你的调试器愿意向你展示简单属性的结果,但是联系数据库对它来说太难了。

Hence, if you really want to see the result of the database query while debugging, you'll have to execute the query, by adding a method of the second group.因此,如果您真的想在调试时查看数据库查询的结果,则必须通过添加第二组的方法来执行查询。 Most often people will temporarily add ToList() .大多数情况下,人们会临时添加ToList()

In your second example you used a method from the second group: the query was executed, and the result was put in local memory: the debugger can access the data, because it only has to check some memory.在第二个示例中,您使用了第二组的方法:执行查询,并将结果放入本地 memory:调试器可以访问数据,因为它只需要检查一些 memory。

So for debugging the solution is simple: add ToList , before examining.因此,调试解决方案很简单:在检查之前添加ToList

Improvements改进

By now, you know that variable a in the first example expresses the potential to fetch data, not the fetched data itself.现在,您知道第一个示例中的变量a表示获取数据的可能性,而不是获取的数据本身。 You obviously simplified your code for the question, you want to do something with the data.您显然简化了问题的代码,您想对数据做一些事情。

  • I'm pretty sure that SSEntities implements IDisposable .我很确定 SSEntities 实现了IDisposable You should Dispose it as soon as you don't need it anymore.您应该在不再需要它时立即将其丢弃。
  • Make sure that you fetch the data (execute the query) before you dispose SSEntities.确保在处置 SSEntities 之前获取数据(执行查询)。

Usually people use the following structure to make sure that the object is disposed properly in all circumstances:通常人们使用以下结构来确保 object 在所有情况下都正确配置:

using (SSEntities db = new SSEntities())
{
    var myQuery = db.Custs.Select(cust => new {...});

    // execute the query:
    var fetchedData = myQuery.ToList();
}

Be aware for the following pitfall:请注意以下陷阱:

IQueryable<Cust> GetCustomers()
{
    using (SSEntities db = new SSEntities())
    {
        return db.Custs.Select(cust => new {...});
    }
}

The query is not executed, yet you've disposed SSEntities.查询未执行,但您已处置 SSEntities。 Your compiler won't complain, you'll get an exception at runtime.你的编译器不会抱怨,你会在运行时得到一个异常。

The proper solution is to let your caller create and dispose the connection with the database, you only provide the selection:正确的解决方案是让您的调用者创建和处理与数据库的连接,您只需提供选择:

static IQueryable<Cust> GetCustomersByPostCode(this IQueryable<Cust> customers,
       PostCode postCode)
{
    return customers.Where(customer => customer.PostCode == postCode)
                    .Select(customer => new {...});
}

Usage:用法:

protected void Page_Load(object sender, EventArgs e)
{
    List<Customer> customers = null;
    using (SSEntities db = new SSEntities())
    {
    
        PostCode postCode = ...
        customers = db.Customers.GetCustomersByPostCode(postCode).ToList();
    }

    // the database is disposed, cannot be used anymore
    // customers already fetched, can still be used:
    ProcessFetchedCustomers(customers);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 功能评估需要运行所有线程 - The function evaluation requires all threads to run 调试期间的 Visual Studio:function 评估需要所有线程运行 - Visual Studio during Debugging: The function evaluation requires all threads to run 懒 <T> :“功能评估需要所有线程运行” - Lazy<T>: “The function evaluation requires all threads to run” 虚拟列表 <T> :“功能评估需要所有线程运行” - virtual List<T> :“The function evaluation requires all threads to run” VS2015 Watch LINQ var错误:函数评估需要运行所有线程 - VS2015 Watch LINQ var Error: The function evaluation requires all threads to run 如何在没有“函数求值要求所有线程都运行”的情况下在后台调用方法 - How can I call a method in the background without “The function evaluation requires all threads to run” EntityFramework中的SaveChanges()不保存更改。 显示“函数评估要求所有线程都运行” - SaveChanges() in EntityFramework not saving changes. Showing “The function evaluation requires all threads to run” ASP.NET MVC或更多VS调试问题-EF / Sql函数评估要求所有线程都运行[保持] - ASP.NET MVC or more of a VS debugging issue - EF/ Sql The function evaluation requires all threads to run [on hold] 使用 Cosmos ExecuteQuery 查询 azure 表存储时,为什么会出现“function 评估需要所有线程运行”? - Why do i get "The function evaluation requires all threads to run" when querying an azure table storage with Cosmos ExecuteQuery? VS自定义可视化工具中的“ new AdhocWorkspace()”之后,“此函数需要所有线程进行评估” - “This function requires all threads to evaluate” after `new AdhocWorkspace()` within VS custom visualizer
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM