zzzprojects / EntityFramework-Plus

Entity Framework Plus extends your DbContext with must-haves features: Include Filter, Auditing, Caching, Query Future, Batch Delete, Batch Update, and more
https://entityframework-plus.net/
MIT License
2.27k stars 318 forks source link

Update creates invalid query EntityFramework-Plus with EF6 on Postgresql #778

Closed Muhahe closed 1 year ago

Muhahe commented 1 year ago

1. Description

Im trying to increment value in postgresql database by Update() method, but i always getting invalid SQL query. I tried both codeFirst and both DB first approach but without difference.

My database table looks like this

    public partial class downloader_assembly_test_statistics
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int assembly_id { get; set; }

        public int tests_ran { get; set; }

        public int tests_passed { get; set; }
    }

Then im trying this piece of code (based on online example)

repository.DbSet.Update(x => new downloader_assembly_test_statistics
{
    tests_passed = x.tests_passed + 5,
    tests_ran = x.tests_ran + 8
});

I also tried it in dotnetfiddle and there it works, but in my case, when im using postresql database my query looks like

UPDATE "schema"."downloader_assembly_test_statistics"
SET "tests_passed" = "tests_passed" + 5 AS "C1" ,
"tests_ran" =  "tests_ran" + 8 AS "C1"
WHERE EXISTS ( SELECT 1 FROM (SELECT "Extent1"."assembly_id"
    , "Extent1"."tests_ran"
    , "Extent1"."tests_passed" FROM "schema"."downloader_assembly_test_statistics" AS "Extent1") B
    WHERE "schema"."downloader_assembly_test_statistics"."assembly_id" = B."assembly_id"
    )

where you can see that AS "C1" on line 2 and 3 makes this query invalid

When i try this, without increment to just setup value

repository.DbSet.Update(x => new downloader_assembly_test_statistics()
{
    tests_passed = 5,
    tests_ran = 8,

});

query is okay

UPDATE "schema"."downloader_assembly_test_statistics"
SET "tests_passed" = :zzz_BatchUpdate_0,
"tests_ran" = :zzz_BatchUpdate_1
WHERE EXISTS ( SELECT 1 FROM (SELECT "Extent1"."assembly_id", "Extent1"."tests_ran", "Extent1"."tests_passed" FROM "schema"."downloader_assembly_test_statistics" AS "Extent1") B
               WHERE "schema"."downloader_assembly_test_statistics"."assembly_id" = B."assembly_id"
           )  

2. Exception

If you are seeing an exception, include the full exception details (message and stack trace).

UPDATE "schema"."downloader_assembly_test_statistics"
SET "tests_passed" =  "tests_passed" + 5 AS "C1" ,
"tests_ran" =  "tests_ran" + 8 AS "C1" 
WHERE EXISTS ( SELECT 1 FROM (SELECT "Extent1"."assembly_id", "Extent1"."tests_ran", "Extent1"."tests_passed" FROM "schema"."downloader_assembly_test_statistics" AS "Extent1") B
               WHERE "schema"."downloader_assembly_test_statistics"."assembly_id" = B."assembly_id"
           )  

-- Executing at 20.09.2023 13:40:12 +02:00

-- Failed in 247 ms with error: 42601: syntax error at or near "AS"

POSITION: 97

3. Fiddle or Project

I tried this on modified fiddle you provide in documentation but unfortunatelly it works there. So im realy confused.

4. Any further technical details

My project is .Net Framework 4.7.2 with nuget packages

 <package id="EntityFramework" version="6.4.4" targetFramework="net472" />
  <package id="EntityFramework6.Npgsql" version="6.4.3" targetFramework="net472" />
  <package id="Microsoft.Bcl.AsyncInterfaces" version="6.0.0" targetFramework="net472" />
  <package id="Microsoft.Bcl.HashCode" version="1.1.1" targetFramework="net472" />
  <package id="Microsoft.Extensions.DependencyInjection" version="3.1.5" targetFramework="net472" />
  <package id="Microsoft.Extensions.DependencyInjection.Abstractions" version="3.1.5" targetFramework="net472" />
  <package id="Microsoft.Extensions.Logging.Abstractions" version="6.0.0" targetFramework="net472" />
  <package id="Npgsql" version="6.0.7" targetFramework="net472" />
  <package id="System.Buffers" version="4.5.1" targetFramework="net472" />
  <package id="System.Collections.Immutable" version="6.0.0" targetFramework="net472" />
  <package id="System.Diagnostics.DiagnosticSource" version="6.0.0" targetFramework="net472" />
  <package id="System.Memory" version="4.5.4" targetFramework="net472" />
  <package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
  <package id="System.Runtime.CompilerServices.Unsafe" version="6.0.0" targetFramework="net472" />
  <package id="System.Text.Encodings.Web" version="6.0.0" targetFramework="net472" />
  <package id="System.Text.Json" version="6.0.0" targetFramework="net472" />
  <package id="System.Threading.Channels" version="6.0.0" targetFramework="net472" />
  <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
  <package id="System.ValueTuple" version="4.5.0" targetFramework="net472" />
JonathanMagnan commented 1 year ago

Hello @Muhahe ,

Thank you for reporting, my developer will look at it.

Best Regards,

Jon

Muhahe commented 1 year ago

Hello @JonathanMagnan,

Thank you for quick reply, if there is anything more i can provide you to help with this, please let me know.

In meantime i tried this with Entity framework Classic -> UpdateFromQuery alternative and result was same for me.

So maybe is this even possible with Npgsql provider?

Regards Muhahe

JonathanMagnan commented 1 year ago

Hello @Muhahe ,

A new version of EF Plus has been released today.

This issue should have been fixed. The fix for EF Classic will be deployed next month.

Let me know if everything works as expected.

Best Regards,

Jon

Muhahe commented 1 year ago

Hello @JonathanMagnan

thank you verry much for quick response and fix. Now it works like a charm for me.

Best regards, Lubos