【发布时间】:2019-08-13 00:37:12
【问题描述】:
为了替换以下查询,该查询生成 IN 子句,其中包含 100 多个元素并需要 8.4 秒:
List<AnalysisModel> analyses = AppDbContext.Analysis.Where(m => Id.Contains(m.TestId) & phasesAll.Contains(m.PhaseId)).AsNoTracking().ToList();
我使用手动查询:
string analysisQuery = $"SELECT id, time, compound, reagent, product, phase, conc, test_id FROM public.analysis INNER JOIN (VALUES {stringHelper.WrapGuidToString(Id, GuidWrapper) } ) testid_val (v) ON (test_id = v) INNER JOIN (VALUES {stringHelper.WrapIntToString(phasesAll, IntWrapper) }) phase_val (p)ON (phase = p)";
List<AnalysisModel> analyses = AppDbContext.Analysis.FromSql(analysisQuery).AsNoTracking().ToList();
如果我在 pgAdmin 中执行在analysisQuery 中生成的查询,它会执行并提供与第一个表达式相同的表(在 0.9 秒内)。但是,当我通过FromSql 执行时,我收到以下错误:
System.FormatException: '索引(从零开始)必须大于或 等于零且小于参数列表的大小。'
有什么建议为什么FromSql 在这里不能正常工作?
stringHelper.WrapGuidToString() 和 stringHelper.WrapIntToString() 将 Guid 和字符串包装成适当的格式,例如({Guid1})、({Guid2}) 和 (1)、(2) 分别用于 Guid 和 Int。通过此方法生成的查询可以在 pgAdmin 中毫无问题地执行:
public string WrapIntToString(List<int> input, WrapModel wrapper)
{
List<string> prep = new List<string>();
input.ForEach(m => prep.Add(wrapper.LeftWrapper + m.ToString() + wrapper.RightWrapper));
return string.Join(wrapper.Separator, prep);
}
WrapGuidToString代码:
public string WrapGuidToString(List<Guid> input, WrapModel wrapper)
{
List<string> prep = new List<string>();
input.ForEach(m => prep.Add(wrapper.LeftWrapper + m.ToString() + wrapper.RightWrapper));
return string.Join(wrapper.Separator, prep);
}
wrapper 在哪里
private WrapModel GuidWrapper => new WrapModel()
{
LeftWrapper = "('{",
RightWrapper = "}'::uuid)",
Separator = ","
};
【问题讨论】:
-
错误在代码的哪一部分准确返回。
-
在
List<AnalysisModel> analyses = AppDbContext.Analysis.FromSql(analysisQuery).AsNoTracking().ToList();. -
FromSql是你的 dll 吗?如果没有,你能在这里展示一些细节吗?FromSql -
FromSql是 EF .Net Core 的一部分,我不知道它背后是什么:docs.microsoft.com/en-us/ef/core/querying/raw-sql -
您是否尝试通过简单的查询运行
FromSql?类似select id, time, compound, from public.analysis然后将此查询传递给您的FromSql(analysisQuery)
标签: c# postgresql .net-core entity-framework-core