简体   繁体   English

PostgreSQL提供程序向Entity Framework for Contains和Concat生成的查询错误

[英]Wrong query generated by PostgreSQL provider to Entity Framework for Contains and Concat

I'm using EF to connect to PostgreSQL. 我正在使用EF连接到PostgreSQL。 EF is in 5.0 version, Npgsql in 2.0.14.3. EF是5.0版,Npgsql是2.0.14.3。

The query that I want to run is: 我要运行的查询是:

var list = new List<string> { "test" };

var res = from t in db.Test
    where !list.Contains(string.Concat(t.test1, "_", t.test2))
    select t;
res.ToList();

The query that is generated is something like: 生成的查询类似于:

SELECT "Extent1"."id" AS "id","Extent1"."test1" AS "test1","Extent1"."test2" AS "test2" FROM "public"."test" AS "Extent1" WHERE 'test'!="Extent1"."test1" || '_' || "Extent1"."test2"

And when I run it I get an error: argument of WHERE must be type boolean, not type text . 当我运行它时,我得到一个错误: argument of WHERE must be type boolean, not type text

However, when I change != to = it works. 但是,当我将!=更改为=它可以工作。 It works also when I add a parantheses around concatenated strings in Postgres but I cannot change the query that EF generates. 当我在Postgres中的连接字符串周围添加一个括号,但无法更改EF生成的查询时,它也起作用。

The workaround is that I add the second (dummy) element to the list because then EF generates a bit different query but it isn't an elegant solution… 解决方法是,我将第二个(虚拟)元素添加到列表中,因为随后EF生成了一些不同的查询,但这不是一个很好的解决方案……

Is it a bug in pgSQL? 这是pgSQL中的错误吗? Or maybe in EF provider? 还是在EF提供程序中? Can you suggest a better solution to that problem? 您能为这个问题提出更好的解决方案吗?

MORE INFORMATION 更多信息

The table script: 表脚本:

CREATE TABLE test
(
  test1 character varying(255),
  test2 character varying(255),
  id integer NOT NULL,
  CONSTRAINT "PK" PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

The class for the table: 该表的类:

[Table("test", Schema = "public")]
public class Test
{
    [Key]
    public int id { get; set; }

    public string test1 { get; set; }

    public string test2 { get; set; }
}

App.config: App.config中:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
  </entityFramework>
  <connectionStrings>
    <add name="local" connectionString="Server=localhost;Port=5432;Database=test;User Id=user;Password=password;" providerName="Npgsql" />
  </connectionStrings>
  <system.data>
    <DbProviderFactories>
      <add name="Npgsql Data Provider" invariant="Npgsql" description="Data Provider for PostgreSQL" type="Npgsql.NpgsqlFactory, Npgsql" />
    </DbProviderFactories>
  </system.data>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
  </startup>
</configuration>

Yes, that's a bug in the EF provider Npgsql. 是的,那是EF提供程序Npgsql中的错误。

According to http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE , != and || http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE!=|| are among (any other) , which means they have the same precedence. (any other) ,这意味着它们具有相同的优先级。 They are also left associative, so that query will be parsed as 它们也保持关联,因此查询将被解析为

SELECT ... FROM "public"."test" AS "Extent1"
WHERE ((('test'!="Extent1"."test1") || '_') || "Extent1"."test2")

which is wrong. 这是错误的。 The correct parsing would be 正确的解析是

SELECT ... FROM "public"."test" AS "Extent1"
WHERE ('test'!=(("Extent1"."test1" || '_') || "Extent1"."test2"))

= have lower precedence than != so that works. =优先级比!=低,因此可以使用。

A fix for this is included in the pull request at https://github.com/npgsql/Npgsql/pull/256 . 此请求的修复程序包含在https://github.com/npgsql/Npgsql/pull/256的拉取请求中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM