Code First EF Concurrency Token with Guid

1

I am trying to use a Guid as the concurrency token but everytime I try to insert a record there is an exception about null value not being able to be added.

Generated SQL and Exception Message:

Failed executing DbCommand (4ms) [Parameters=[@p0='?' (DbType = Guid), @p1='?' (Size = 10) (DbType = AnsiString), @p2='?' (Size = 150) (DbType = AnsiString)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
INSERT INTO [Application] ([Id], [Code], [Name])
VALUES (@p0, @p1, @p2);
SELECT [Version]
FROM [Application]
WHERE @@ROWCOUNT = 1 AND [Id] = @p0; System.Data.SqlClient.SqlException (0x80131904): Cannot insert the value NULL into column 'Version', table 'MyCompany.dbo.Application'; column does not allow nulls. INSERT fails.
public class Application
    {
        public Guid Id { get; set; }

        public string Name { get; set; }

        public string Code { get; set; }

        // A concurrency token for use with the optimistic concurrency checking
        public Guid Version { get; set; }
    }

With the model Builder:

builder.Property(c => c.Version)
                .IsConcurrencyToken()
                .ValueGeneratedOnAddOrUpdate();

Basically I need advice about what I am doing wrong.

c#
entity-framework
core
asked on Stack Overflow Nov 5, 2019 by Stephen Cossgrove • edited Nov 5, 2019 by Stephen Cossgrove

1 Answer

0

There are few things I see that need correction.

The modelbuilder statement should be modified as below

 modelBuilder.Entity<Application>().Property(app => app.Version).ValueGeneratedOnAddOrUpdate().IsConcurrencyToken();

Bear in mind that there is no value generation strategy that is specified on Version property. When we generate a migration with this state, the generated Migration.cs file assigns a defaultValue new Guid("00000000-0000-0000-0000-000000000000")); inside of the Up() method. Below is an example

Contact Entity

Migration without Required attribute and without any value generation strategy

On the other hand, if you want a new Guid to be added each time you insert a new row into the table, you should use a computed field. Below two images show the structure of the Version property decorated with attributes and the generated Migration. Also, below line code needs to be added to mark the computation.

modelBuilder.Entity<Contact>().Property(t => t.Version).HasComputedColumnSql("NEWID()");

Migration with Computed Field

Updated Entity With Computed Field

With the changes mentioned, you'll have a new Guid successfully generated for every row inserted.

answered on Stack Overflow Nov 5, 2019 by Saikumar Gummaluri

User contributions licensed under CC BY-SA 3.0