2
votes

I'm using the Npgsql .Net data provider for PostgreSQL (version 2.1.0-rc1), Npgsql for Entity Framework (version 2.1.0-rc1) and EF (version 6.0.2) Code First migrations. In my entities I have:

public int RowVersion { get; set; }

I also have configuration classes that inherit from EntityTypeConfiguration for each entity and in there I have specified:

this.Property(m => m.RowVersion).IsConcurrencyToken().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);

My problem occurs when I try to update an entity. My update method queries the database to get the entity and then simply modifies the fields, adds a modified date and then calls the following overridden SaveChanges:

public override int SaveChanges() {
        var objectContextAdapter = this as IObjectContextAdapter;

        if (objectContextAdapter != null) {
            objectContextAdapter.ObjectContext.DetectChanges();

            foreach (ObjectStateEntry entry in objectContextAdapter.ObjectContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified)) {
                var v = entry.Entity as BaseEntity;

                if (v != null) {
                    v.RowVersion++;
                }
            }
        }

        return base.SaveChanges();
    }

The current RowVersion in the database is 0. When the code is run EF generates the following SQL (from EF Profiler):

UPDATE "dbo"."Car" SET "IsObsolete"=cast(TRUE as boolean), "DateModified"=TIMESTAMP'2014-03-25T15:48:33.5833236+00:00',"ModifiedById"=1 WHERE "CarId"=32) AND ("RowVersion"=0)

This seems fine and when I run the SQL against the database directly it updates successfully however in Visual Studio I get the following error:

An exception of type 'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException' occurred in EntityFramework.dll but was not handled in user code. Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

This is my first time using EF with PostgreSQL. Does anyone have any suggestions for solving this?

1
I would suggest that the issue is the update query doesn't actually return anything. EF expects a single row to be returned. If no rows are returned it assumes that there was a change to the RowVersion numberAndrew Harry

1 Answers

1
votes

Isn't this what you wanted to happen? You should catch the DbUpdateConcurrencyException exception then from there you can either load(refresh) the values from the database and notify your user or proceed with save (client wins) after updating your row version from the value currently stored in the database.