Question

Is it possible to use the CodeFirst architecture to implement the Guid COMB identification approach for objects in the brand-new Entity Framework 4.1? I believed putting theStoreGeneratedPattern would be effective, but it still produces standard GUIDs.

1
9
3/5/2016 7:17:07 AM

Accepted Answer

I'm assuming your database is SQL server. This is a good illustration of the inconsistencies between various MS tools. The SQL Server team advises against usingnewid() is a default setting forUNIQUEIDENTIFIER If you specify, the ADO.NET team and columns will utilize it.Guid since it was automatically produced in the database. They ought to utilizenewsequentialid() instead!

It is quite difficult to edit a produced table to get sequential Guids from a database since you have to locate the autogenerated default constraint, remove it, and add a new constraint. All of this is possible with a custom database initializer. Here is a snippet of my code:

class Program
{

    static void Main(string[] args)
    {
        Database.SetInitializer(new CustomInitializer());
        using (var context = new Context())
        {
            context.TestEntities.Add(new TestEntity() { Name = "A" });
            context.TestEntities.Add(new TestEntity() { Name = "B" });
            context.SaveChanges();
        }
    }
}

public class CustomInitializer : DropCreateDatabaseAlways<Context>
{
    protected override void Seed(Context context)
    {
        base.Seed(context);

        context.Database.ExecuteSqlCommand(@"
            DECLARE @Name VARCHAR(100)

            SELECT @Name = O.Name FROM sys.objects AS O
            INNER JOIN sys.tables AS T ON O.parent_object_id = T.object_id
            WHERE O.type_desc LIKE 'DEFAULT_CONSTRAINT' 
              AND O.Name LIKE 'DF__TestEntities__Id__%'
              AND T.Name = 'TestEntities'

            DECLARE @Sql NVARCHAR(2000) = 'ALTER TABLE TestEntities DROP Constraint ' + @Name

            EXEC sp_executesql @Sql

            ALTER TABLE TestEntities
            ADD CONSTRAINT IdDef DEFAULT NEWSEQUENTIALID() FOR Id");
    }
}

public class TestEntity
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class Context : DbContext
{
    public DbSet<TestEntity> TestEntities { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<TestEntity>()
            .Property(e => e.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
}
9
5/23/2011 5:20:38 PM

Popular Answer

Why should anybody care about the database's Guid columns' default values? Why not simply have the client produce the Guid like any other value? That necessitates having a function in your client code that will provide guids similar to COMB:

public static Guid NewGuid()
{
    var guidBinary = new byte[16];
    Array.Copy( Guid.NewGuid().ToByteArray(), 0, guidBinary, 0, 8 );
    Array.Copy( BitConverter.GetBytes( DateTime.Now.Ticks ), 0, guidBinary, 8, 8 );
    return new Guid( guidBinary );
}

One benefit of the Guid is that it may be generated on the client without making a second journey to the database.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow