[英]What is the function evaluation requires all threads to run?
我刚刚制作了一张桌子 Cust 和 Ado.net 并创建了一个 dbEntity 来使用 LINQ
但是我收到了这个错误,我无法获取记录。
protected void Page_Load(object sender, EventArgs e)
{
SSEntities db = new SSEntities();
var a = from tb in db.Custs
select tb;
}
连接字符串——
<add name="SSEntities" connectionString="metadata=res://*/DbModel.csdl|res://*/DbModel.ssdl|res://*/DbModel.msl;provider=System.Data.SqlClient;provider connection string="data source=XYZ\SQLEXPRESS;initial catalog=SS;persist security info=True;user id=sa;password=La123;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
错误 - function 评估需要所有线程运行
但这有效
protected void Page_Load(object sender, EventArgs e)
{
SSEntities db = new SSEntities();
var a = db.Custs.FirstOrDefault();
}
您必须了解 LINQ 使用的延迟执行。
假设db.Custs
是一个 object 实现IQueryable<Cust>
或类似的东西。
如果您在第一个示例中检查a
的类型,您会看到它是一个IQueryable<Cust>
。 第二个示例中的一个是Cust
。
如果您检查 LINQ 方法,您会注意到它们有两组:返回IEnumerable<TResult>
(或IQueryable<TResult>
)的一组和不返回的一组。
Select, Join, GroupBy
是第一组的示例。 他们不执行查询。 它们不代表获取的数据,它们代表select 数据的潜力并枚举它。
只要您只连接该组中的函数。 不查询您的数据来源。 这个来源通常是一个数据库,但它可以是任何可枚举的、CSV 文件阅读器、JSON 文件、来自互联网的信息。 在 LINQ 术语中,我们说这些方法使用延迟执行。 您可以在该方法的每个描述中找到该术语。
第二组方法的示例是ToList, FirstOrDefault, Count, Any
:返回不是IQueryable<...>
。 执行其中一个方法将开始枚举作为输入源的 IEnumerable/IQueryable:将获取第一个元素,如果有,并且如果方法需要,将获取序列的其他元素。
您的第一个页面加载将创建查询。 创造了从数据库中获取数据的潜力。 唉,你忘了执行查询。 如果您调试程序,并在断点处停止所有线程,并希望检查 a 的值,您希望查看 object a
的属性。 唉,你的调试器愿意向你展示简单属性的结果,但是联系数据库对它来说太难了。
因此,如果您真的想在调试时查看数据库查询的结果,则必须通过添加第二组的方法来执行查询。 大多数情况下,人们会临时添加ToList()
。
在第二个示例中,您使用了第二组的方法:执行查询,并将结果放入本地 memory:调试器可以访问数据,因为它只需要检查一些 memory。
因此,调试解决方案很简单:在检查之前添加ToList
。
现在,您知道第一个示例中的变量a
表示获取数据的可能性,而不是获取的数据本身。 您显然简化了问题的代码,您想对数据做一些事情。
IDisposable
。 您应该在不再需要它时立即将其丢弃。通常人们使用以下结构来确保 object 在所有情况下都正确配置:
using (SSEntities db = new SSEntities())
{
var myQuery = db.Custs.Select(cust => new {...});
// execute the query:
var fetchedData = myQuery.ToList();
}
请注意以下陷阱:
IQueryable<Cust> GetCustomers()
{
using (SSEntities db = new SSEntities())
{
return db.Custs.Select(cust => new {...});
}
}
查询未执行,但您已处置 SSEntities。 你的编译器不会抱怨,你会在运行时得到一个异常。
正确的解决方案是让您的调用者创建和处理与数据库的连接,您只需提供选择:
static IQueryable<Cust> GetCustomersByPostCode(this IQueryable<Cust> customers,
PostCode postCode)
{
return customers.Where(customer => customer.PostCode == postCode)
.Select(customer => new {...});
}
用法:
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.