Question

Existe-t-il un moyen d'implémenter la stratégie d'identité Guid COMB pour les objets dans le nouveau Entity Framework 4.1 en utilisant la conception CodeFirst ?Je pensais régler le StoreGeneratedPattern cela fonctionnerait, mais cela me donne toujours des GUID normaux.

Était-ce utile?

La solution

Je suppose que vous utilisez le serveur SQL comme base de données.C'est un bel exemple d'incohérence entre les différents outils MS.L'équipe du serveur SQL ne recommande pas d'utiliser newid() comme valeur par défaut pour UNIQUEIDENTIFIER les colonnes et l'équipe ADO.NET l'utilisent si vous spécifiez Guid propriété telle que générée automatiquement dans la base de données.Ils devraient utiliser newsequentialid() plutôt!

Si vous souhaitez des Guids séquentiels générés par la base de données, vous devez modifier la table générée et c'est vraiment complexe car vous devez trouver la contrainte par défaut générée automatiquement, la supprimer et créer une nouvelle contrainte.Tout cela peut être fait dans un initialiseur de base de données personnalisé.Ici vous avez mon exemple de 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);
    }
}

Autres conseils

Pourquoi s'inquiéter des valeurs par défaut des colonnes Guid dans la base de données ?Pourquoi ne pas simplement générer le Guid sur le client comme n'importe quelle autre valeur.Cela nécessite que vous ayez une méthode dans votre code client qui générera des guids de type 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 );
}

L'un des avantages du Guid est précisément que vous pouvez les générer sur le client sans aller-retour vers la base de données.

La réponse la plus simple

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

Cela suppose que votre table de base de données est définie avec la valeur par défaut de newsequentialid() qui dans mon cas est géré par les migrations FluentMigrator.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top