为了替换下面的查询,该查询在内部生成100个以上的元素并耗时8.4秒的IN子句:
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 s内)。但是,当我通过FromSql
执行时,收到以下错误:
System.FormatException:'索引(从零开始)必须大于或 等于零且小于参数列表的大小。'
有何建议FromSql
在这里不能正常工作?
stringHelper.WrapGuidToString()
和stringHelper.WrapIntToString()
将Guid和string包装为适当的格式,例如({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 = ","
};
答案 0 :(得分:0)
我遇到了你的问题:
wrapper.LeftWrapper + m.ToString() + wrapper.RightWrapper
似乎您已经创建了一种字符串格式{yourStringValueHere}
,这就是为什么出现此错误Zero index
String.Format("{0}{1}{2}","Value1","Value2","Value3")
看起来一定是这样。
这个m.ToString()
和您的包装器是错误的,而不是integer
然后是值
看看WrapGuidToString
或WrapIntToString
的格式是否正确。这是您的主要问题。