I'm using EF to connect to PostgreSQL. EF is in 5.0 version, Npgsql in 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
.
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.
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…
Is it a bug in pgSQL? Or maybe in EF provider? 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:
<?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.
According to http://www.postgresql.org/docs/9.3/static/sql-syntax-lexical.html#SQL-PRECEDENCE-TABLE , !=
and ||
are among (any other)
, which means they have the same precedence. 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 .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.