根據檔案 SqlCommandTimeout是
此屬性是命令執行或結果處理期間所有網路讀取的累積超時(對于在呼叫方法期間讀取的所有網路資料包)。回傳第一行后仍然會出現超時,不包括用戶處理時間,只包括網路讀取時間。
例如,超時時間為 30 秒,如果讀取需要兩個網路資料包,那么它有 30 秒的時間讀取兩個網路資料包。如果您再次呼叫 Read,它將再有 30 秒的時間來讀取它需要的任何資料。
我有下面的代碼執行存盤程序,然后使用 SqlReader 逐行讀取資料。
public static async Task<IEnumerable<AvailableWorkDTO>> prcGetAvailableWork(this MyDBContext dbContext, int userID)
{
var timeout = 120
var result = new List<AvailableWorkDTO>();
using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
{
var p1 = new SqlParameter("@UserID", SqlDbType.Int)
{
Value = userID
};
cmd.CommandText = "dbo.prcGetAvailableWork";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(p1);
cmd.CommandTimeout = timeout;
await dbContext.Database.OpenConnectionAsync().ConfigureAwait(false);
using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false))
{
while (await reader.ReadAsync().ConfigureAwait(false))
{
var item = new AvailableWorkDTO();
item.ID = reader.GetInt32(0);
item.Name = reader.GetString(1);
item.Title = reader.GetString(2);
item.Count = reader.GetInt32(3);
result.Add(item);
}
}
}
return result;
}
在 Sql Profiler 中,我只看到一個對存盤程序的呼叫,正如預期的那樣。所以我猜測存盤程序執行并回傳整個結果集。
問題
1>如果SqlReader一次讀取一條記錄,那么reader讀取時整個結果集存盤在哪里?它是臨時存盤在 SQL Server 記憶體中還是應用程式服務器記憶體中?
2>使用EF Core有沒有辦法一次性讀取整個結果集?
uj5u.com熱心網友回復:
結果集不存盤在任何地方,它直接流式傳輸到客戶端。當服務器從磁盤或記憶體讀取行時,它們通過查詢計劃饋送并通過網路輸出。這就是為什么您總是需要確保盡可能快地讀取并處理讀取器和連接:因為查詢一直在運行。
要“一次讀取整個結果集”,您只需執行您現在正在執行的操作:回圈讀取器并將其添加到List. 或者,您可以使用DataTable.Load,但我不建議這樣做,也不是async。
讀取器只是一個能夠從命令回傳單個行的物件。您在探查器中看到的是命令的單次執行。如果您還監視SQL:Batch Completed事件,您將看到只有在閱讀器完成時才會發生。
uj5u.com熱心網友回復:
您可以將存盤程序與 EF 而不是 ADO.Net 一起使用,但我不確定它會更快。
創建一個特殊的類以從 sp 獲取資料或使用現有的 AvailableWorkDTO。此類應具有存盤程序的 select 子句所具有的所有屬性。您不需要在存盤程序中選擇所有內容。只需選擇 AvailableWorkDTO 具有的屬性并添加 NotMapped 屬性
[NotMapped]
public class AvailableWorkDTO
{
.....
}
在此之后將此類添加到 dbContext DbSet
public virtual DbSet<AvailableWorkDTO> AvailableWorkDTOs { get; set; }
這是一個示例函式,用于展示如何使用存盤程序獲取資料
public async Task<IEnumerable<AvailableWorkDTO>> prcGetAvailableWork(MyDBContext dbContext, int userID)
{
var pId = new SqlParameter("@UserID", userID);
return await dbContext.Set<AvailableWorkDTO>()
.FromSqlRaw("Execute db.prcGetAvailableWork @UserID", pId)
.ToArrayAsync();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/337388.html
標籤:sql-server 实体框架 .net核心 实体框架核心 asp.net-core-mvc
