¿Hay alguna forma de implementar la estrategia de identidad Guid COMB para objetos en el nuevo Entity Framework 4.1 utilizando el diseño CodeFirst? Pensé que configurar el StoreGeneratedPattern
funcionaría, pero todavía me da GUID normales.Estrategia GUID COMB en EF
Respuesta
Supongo que está utilizando el servidor SQL como su base de datos. Este es un buen ejemplo de inconsistencia entre las diferentes herramientas de MS. El equipo del servidor SQL no recomienda usar newid()
como valor predeterminado para las columnas UNIQUEIDENTIFIER
y el equipo ADO.NET lo usa si especifica la propiedad Guid
como autogenerada en la base de datos. ¡Deberían usar newsequentialid()
en su lugar!
Si desea Guias secuenciales generados por la base de datos, debe modificar la tabla generada y es realmente compleja porque debe encontrar la restricción predeterminada autogenerada, soltarla y crear una nueva restricción. Todo esto se puede hacer en el inicializador de base de datos personalizado. Aquí tienes mi código de ejemplo:
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);
}
}
Esto parece innecesario. Realmente había esperado que el 4.1 EF fuera más robusto que esto. Muchas gracias por aclararme esto, funcionó perfectamente. – Ciel
Recomiendo encarecidamente no hacer cosas como esta en el método de la semilla. En cambio, pertenece a una migración separada. Se llamará semilla cada vez que se active una migración. No diciendo que esta no es una solución correcta, solo que se desencadena en el lugar equivocado. –
@CasperLeonNielsen: escribí este ejemplo durante mucho tiempo antes de que EF obtuviera la API de migración. Puede agregar una nueva respuesta con la migración para actualizarla. –
¿Por qué preocuparse por defecto para las columnas GUID en la base de datos en absoluto? ¿Por qué no generar el Guid en el cliente como cualquier otro valor? Eso requiere que tengas un método en su código de cliente que va a generar los GUID de peine:
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);
}
Una de las ventajas del GUID es específicamente que se puede generarlos en el cliente sin necesidad de volver a la base de datos.
+1 Si definir COMB como Guids es tan fácil, puede combinar este código con esto: http://stackoverflow.com/questions/5275306/does-entity-framework-4-code-first-have-support-for-identity -generators-like-nhib/5277642 # 5277642 y obtienes el inicializador guid.comb. –
Tuve un momento difícil eligiendo entre las dos respuestas, ya que ambas inevitablemente condujeron al mismo resultado. Ambos son útiles. Muchas gracias por esta información, funciona muy bien. – Ciel
El uso de Guids generados secuencialmente hará que la indexación sea menos compleja en el servidor SQL. –
La respuesta más 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; }
}
Esto supone que tiene su tabla de base fija con el valor por defecto de newsequentialid()
que en mi caso es administrado por migraciones FluentMigrator.
Para que esto ayude a otros, necesita un ejemplo de "Migraciones de FluentMigrator" –
@CasperLeonNielsen que no es realmente cierto, requiere que el esquema de la tabla tenga un conjunto predeterminado. La forma en que establece el valor predeterminado de 'newsequentialid()' está realmente fuera del alcance de esta pregunta y se convierte en una preocupación genérica de esquema sql. –
http://stackoverflow.com/questions/12257465/update-row-data-with-a-new-value-per-row-using-fluentmigrator –
- 1. Base de datos SQL Server con PK GUID en clúster: ¿cambiar de índice agrupado o cambiar a GUID secuenciales (comb)?
- 2. Valor de rendimiento de las guías COMB
- 3. Cómo convertir guid? guid
- 4. EF: En busca de una estrategia de diseño para DatabaseFirst DbContext de una Aplicación modular
- 5. GUID secuencial en Linq-to-Sql?
- 6. Convirtiendo un Guid a Nullable Guid
- 7. EF 4.1 estropeando las cosas. ¿Ha cambiado la estrategia de nombres FK?
- 8. Cómo validar GUID es un GUID
- 9. Referenciando GUID
- 10. Entity Framework - SaveChanges con GUID como EntityKey
- 11. EF 4.1 error de integridad referencial
- 12. @GeneratedValue (estrategia = "IDENTIDAD") vs. @GeneratedValue (estrategia = "SECUENCIA")
- 13. ¿Dónde se encuentra modelBuilder.IncludeMetadataInDatabase en EF CTP5?
- 14. Crear un GUID en Java
- 15. ¿Puedo mostrar GUID en windbg?
- 16. GUID en un archivo SLN
- 17. ¿Cómo obtener GUID en android?
- 18. Cómo validar Guid en .net
- 19. FlavorProperties GUID en csproj Archivo
- 20. Insertar GUID en SQL Server
- 21. EF 4.1 RC de muchos a muchos en EF CF
- 22. Prueba con un guid ... ¿cómo configuro la variable como Guid?
- 23. Código EF Primero con muchas referencias autorreferenciales
- 24. Patrón de estrategia en Symfony2
- 25. GUID vs INT IDENTIDAD
- 26. Generación de GUID
- 27. cómo crear GUID?
- 28. Validación de Guid
- 29. interfaz COM Guid
- 30. Entity Framework Guid
Supongo que ya ha comprobado el valor predeterminado del lado del servidor de base de datos? –
Sí, tengo. No lo encontré para resolver mi problema. – Ciel