以下語法在遷移到 EF Core 時出現以下錯誤
>h__TransparentIdentifier1 = <>h__TransparentIdentifier1, ijpGroup = ijpGroup })' 無法翻譯。以可翻譯的形式重寫查詢,或通過插入對“AsEnumerable”、“AsAsyncEnumerable”、“ToList”或“ToListAsync”的呼叫顯式切換到客戶端評估。看https://go.microsoft.com/fwlink/?linkid=2101038 了解更多資訊。
(from ij in ImportJobs
join id in ImportDefinitions
on ij.ImportDefinitionId equals id.ImportDefinitionId
join it in ImportTypes
on id.ImportTypeId equals it.ImportTypeId
join ijp in ImportJobParameters
on ij.ImportJobId equals ijp.ImportJobId into ijpGroup
where ij.JobQueuedTimeUtc >= DateTime.Now.AddDays(-30)
orderby ij.JobQueuedTimeUtc descending
select
new
{
ImportDefinition = id,
ImportType = it,
LastImportJob = ij,
LastImportJobParameters = ijpGroup
}).ToList()
我試圖改變這一點如下
(from ij in ImportJobs
join id in ImportDefinitions
on ij.ImportDefinitionId equals id.ImportDefinitionId
join it in ImportTypes
on id.ImportTypeId equals it.ImportTypeId
from ijp in ImportJobParameters.Where(ijp => ij.ImportJobId == ijp.ImportJobId).DefaultIfEmpty()
where ij.JobQueuedTimeUtc >= DateTime.Now.AddDays(-60)
orderby ij.JobQueuedTimeUtc descending
select
new
{
ImportDefinition = id,
ImportType = it,
LastImportJob = ij,
LastImportJobParameter = ijp
}).ToList()
.GroupBy(i => new { i.ImportDefinition, i.ImportType, i.LastImportJob })
.Select(i => new { i.Key.ImportDefinition, i.Key.ImportType, i.Key.LastImportJob, LastImportJobParameters = i.Select(s => s.LastImportJobParameter) })
但是,這會導致 LastImportJobParameters 的 IEnumerable 有 1 個 null 項,而以前會有 0 個項。只是想知道是否有等效的 EF Core 陳述句,否則我將在實作后過濾掉。
**類簡化**
public class ImportJob
{
[Key]
public int? ImportJobId { get; set; }
[Required]
public Int16? ImportDefinitionId { get; set; }
[NotMapped]
public ImportDefinition ImportDefinition { get; set; }
public DateTime? JobQueuedTimeUtc { get; set; }
[NotMapped]
public List<ImportJobParameter> ImportJobParameters { get; set; }
}
public class ImportJobParameter
{
[Key]
public int? ImportJobParameterId { get; set; }
[Required]
public int? ImportJobId { get; set; }
[Required]
public short? ImportParameterId { get; set; }
public string ParameterName { get; set; }
public string ParameterValue { get; set; }
}
public class ImportDefinition
{
[Key]
public Int16? ImportDefinitionId
{
get;
set;
}
[Required]
[StringLength(255)]
public string Name
{
get;
set;
}
public ImportType ImportType
{
get;
set;
}
[Required]
public Int16? ImportTypeId
{
get;
set;
}
}
public class ImportType
{
[Key]
public Int16? ImportTypeId
{
get; set;
}
[Required]
[StringLength(100)]
public string Name
{
get;
set;
}
}
uj5u.com熱心網友回復:
不要使用 GroupJoin 進行預加載,僅用于 LEFT JOIN。EF Core 團隊不會修復此限制。進行子查詢以檢索詳細資料:
var query =
from ij in ImportJobs
join id in ImportDefinitions
on ij.ImportDefinitionId equals id.ImportDefinitionId
join it in ImportTypes
on id.ImportTypeId equals it.ImportTypeId
where ij.JobQueuedTimeUtc >= DateTime.Now.AddDays(-30)
orderby ij.JobQueuedTimeUtc descending
select new
{
ImportDefinition = id,
ImportType = it,
LastImportJob = ij,
LastImportJobParameters = ImportJobParameters
.Where(ijp => ij.ImportJobId == ijp.ImportJobId)
.ToList()
};
uj5u.com熱心網友回復:
真正且可能更快的解決方案是修復物體模型并消除連接。事實上,看起來您所要做的就是洗掉[NotMapped]并寫入:
var flattened=context.Jobs
.Where(job=>job.JobQueuedTimeUtc >= date)
.Select(job=>new {
ImportDefinition = job.ImportDefinition ,
ImportType = job.ImportDefinition.ImportType,
LastImportJob = job,
LastImportJobParameter = job.ImportJobParameters
}).ToList()
原始查詢所做的是GroupJoin,這是一種在 SQL 中沒有等效項的客戶端操作。EF 執行 LEFT JOIN,然后重新組合記憶體中的右側行以重建Parameters集合。這是一個昂貴的客戶端操作,它可以加載到比程式員意識到的更多的記憶體中,尤其是當他們試圖過濾右手物件時。EF Core 不支持這個
在許多情況下,GroupJoin 不會轉換到服務器。它要求您從服務器獲取所有資料以在沒有特殊選擇器的情況下進行 GroupJoin(下面的第一個查詢)。但是如果選擇器限制了被選擇的資料,那么從服務器獲取所有資料可能會導致性能問題(下面的第二個查詢)。這就是 EF Core 不翻譯 GroupJoin 的原因。
如果右手是一個執行日志,例如每個作業執行 10K 次,則執行 GroupJoin 以獲取最后 10 個將導致所有日志被加載并在記憶體中排序,只有 99.9% 的日志被拒絕。
第二個查詢所做的是模擬 GroupJoin,通過執行 LEFT JOIN,然后對記憶體中的物件進行分組。由于這是一個 LEFT JOIN,所以右手邊應該有空值。
要獲得您想要的結果,您必須過濾引數,然后將它們轉換為串列或陣列。否則,每次您嘗試訪問LastImportJobParametersLINQ 子查詢時都會再次運行:
.Select(i => new {
i.Key.ImportDefinition,
i.Key.ImportType,
i.Key.LastImportJob,
LastImportJobParameters = i.Where(s.LastImportJobParameter!=null)
.Select(s => s.LastImportJobParameter)
.ToList() })
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/524142.html
標籤:实体框架实体框架核心
上一篇:如何正確地將環境變數發送到影像?
下一篇:當資料庫中的外鍵關系為空時使用OdataAPI,拋出SqlNullValueException:DataisNull例外
