[英]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.