【问题标题】:FromSql results in error, while query is working in pgAdminFromSql 导致错误,而查询在 pgAdmin 中工作
【发布时间】: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&lt;AnalysisModel&gt; 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


【解决方案1】:

我有你的问题:

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

您似乎创建了一个字符串格式{yourStringValueHere},这就是您收到此错误Zero index的原因

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

一定是这样的。

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

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

【讨论】:

  • 不,我正在生成的 Sql 查询示例:SELECT id, compound, conc, phase, product, reagent, test_id, time FROM public.analysis INNER JOIN (VALUES ('{85025e34-b45c-412f-ba45-e2c49d2a3bae}'::uuid),('{11f99597-56a3-44bd-ad6c-9da16143057a}'::uuid) ) testid_val (v) ON (test_id = v) INNER JOIN (VALUES (2),(4),(5),(9)) phase_val (p) ON (phase = p)。同样,它在 pgAdmin 中工作。我的包装方法没有错,它没有创建字符串值,当它看起来像一个字符串时,我通过提供::uuid 来转换正确的类型。看不到您的代码工作。
  • 我认为你的{} VS 认为这是字符串格式。尝试使用像select * from table 这样的简单查询,无需任何连接。如果发生错误。
  • 这样的简单查询很容易处理。如果我没记错FromSql 应该按原样执行并接收表格,然后如果表格格式不正确 - 应该会发生错误。由于查询正在运行,我只能看到FromSql 有问题。由于性能,没有内部连接对我来说毫无意义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 2012-01-09
  • 2020-03-15
  • 2015-10-21
相关资源
最近更新 更多