当查询在pgAdmin中工作时,FromSql导致错误

时间:2019-03-22 03:45:25

标签: c# postgresql .net-core entity-framework-core

为了替换下面的查询,该查询在内部生成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 = ","
};

1 个答案:

答案 0 :(得分:0)

我遇到了你的问题:

wrapper.LeftWrapper + m.ToString() + wrapper.RightWrapper

似乎您已经创建了一种字符串格式{yourStringValueHere},这就是为什么出现此错误Zero index

的原因
String.Format("{0}{1}{2}","Value1","Value2","Value3")

看起来一定是这样。

这个m.ToString()和您的包装器是错误的,而不是integer然后是值

看看WrapGuidToStringWrapIntToString的格式是否正确。这是您的主要问题。