Frage

Gibt es eine Möglichkeit, die Guid-KAMM-Identitätsstrategie für Objekte im neuen Entity Framework 4.1 mithilfe des CodeFirst-Designs zu implementieren?Ich dachte, das Einstellen StoreGeneratedPattern würde funktionieren, aber es gibt mir immer noch normale Anleitungen.

War es hilfreich?

Lösung

Ich vermute, Sie verwenden SQL Server als Datenbank.Dies ist ein schönes Beispiel für Inkonsistenzen zwischen verschiedenen MS-Tools.Das SQL Server-Team empfiehlt die Verwendung nicht newid() als Standardwert für UNIQUEIDENTIFIER spalten und ADO.NET team verwenden Sie es, wenn Sie angeben Guid eigenschaft als automatisch in der Datenbank generiert.Sie sollten verwenden newsequentialid() stattdessen!

Wenn sequentielle Guids von der Datenbank generiert werden sollen, müssen Sie die generierte Tabelle ändern. Dies ist sehr komplex, da Sie eine automatisch generierte Standardeinschränkung finden, löschen und eine neue Einschränkung erstellen müssen.Dies alles kann im benutzerdefinierten Datenbankinitialisierer durchgeführt werden.Hier haben Sie meinen Beispielcode:

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);
    }
}

Andere Tipps

Warum sich überhaupt Gedanken über Standardwerte für Guid-Spalten in der Datenbank machen?Warum generieren Sie nicht einfach die Guid auf dem Client wie jeden anderen Wert.Dazu müssen Sie in Ihrem Client-Code eine Methode haben, die kammartige Guids generiert:

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 );
}

Einer der Vorteile der Guid besteht insbesondere darin, dass Sie sie auf dem Client ohne einen Roundtrip in die Datenbank generieren können.

Die einfachste Antwort

public class User
{
    public User(Guid? id = null, DateTime? created = null)
    {
        if (id != null)
            Id = id;

        if (created != null)
            Created = created;
    }

    public User()
    {
    }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public DateTime? Created { get; internal set; }

    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid? Id { get; internal set; }
}

Dies setzt voraus, dass Sie Ihre Datenbanktabelle mit dem Standardwert von festgelegt haben newsequentialid() was in meinem Fall von FluentMigrator migrations verwaltet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top