forrert
forrert

Reputation: 4199

EntityFramework6 for Npgsql creates invalid update statement

I am using the Npgsql EF6 provider (Npgsql v3.0.5.0). I generated the model from an existing database. I can access the database and read records, but updating existing records fails.

This is a simplified version of my code:

int jobId = 123; // some unique id
Entities entities = new Entities();
Job job = entities.Jobs.First(j => j.Id = jobId);
job.Status = 4;
entities.SaveChanges(); // this line throws an exception

This is the error message I get from this code:

42601: syntax error at or near "("

[NpgsqlException (0x80004005): 42601: syntax error at or near "("]
   Npgsql.NpgsqlConnector.DoReadSingleMessage(DataRowLoadingMode dataRowLoadingMode, Boolean returnNullForAsyncMessage, Boolean isPrependedMessage) +445
   Npgsql.NpgsqlConnector.ReadSingleMessage(DataRowLoadingMode dataRowLoadingMode, Boolean returnNullForAsyncMessage) +282
   Npgsql.NpgsqlCommand.Execute(CommandBehavior behavior) +270
   Npgsql.NpgsqlCommand.ExecuteNonQueryInternal() +177
   Npgsql.NpgsqlCommand.ExecuteNonQuery() +21
   System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<NonQuery>b__0(DbCommand t, DbCommandInterceptionContext`1 c) +26
   System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch(TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) +129
   System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.NonQuery(DbCommand command, DbCommandInterceptionContext interceptionContext) +602
   System.Data.Entity.Internal.InterceptableDbCommand.ExecuteNonQuery() +151
   System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand.Execute(Dictionary`2 identifierValues, List`1 generatedValues) +1045
   System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() +221

This is the query that is being run against the database:

UPDATE (
    SELECT 
        "Jobs"."Id", 
        "Jobs"."Name", 
        "Jobs"."Created", 
        "Jobs"."Status"
    FROM "Jobs"."Jobs" 
    AS "Jobs"
) SET "Status"=$1 WHERE "Id" = $2

I understand that this query obviously won't work with the nested SELECT rather than the table name.

Has someone come across the same error? Is there a setting somewhere that I might miss?

Upvotes: 3

Views: 589

Answers (1)

forrert
forrert

Reputation: 4199

This error was caused by a missing primary key on the affected table.

The .edmx file actually contained the following message:

warning 6002: The table/view '[database.schema.TableName]' does not have a primary key defined. The key has been inferred and the definition was created as a read-only table/view.

Visual Studio also shows the following message in the output tab when updating the model from the database (which I must have missed the first time the model was generated):

The model was generated with warnings or errors.ServiceModel.edmxPlease see the Error List for more details. These issues must be fixed before running your application.

Upvotes: 2

Related Questions