¿Hay alguna manera de crear un índice en una propiedad / columna usando el código primero, en lugar de usar el nuevo IndexAttribute
?
¿Hay alguna manera de crear un índice en una propiedad / columna usando el código primero, en lugar de usar el nuevo IndexAttribute
?
Respuestas:
Bueno, el 26.10.2017 Entity Framework 6.2 se lanzó oficialmente . Incluye la posibilidad de definir índices con facilidad a través de Fluent API. Ho es usar ya estaba anunció en la beta de 6.2.
Ahora puede usar el HasIndex()
método, seguido de IsUnique()
si debe ser un índice único.
Solo un pequeño ejemplo de comparación (antes / después):
// before
modelBuilder.Entity<Person>()
.Property(e => e.Name)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute { IsUnique = true }));
// after
modelBuilder.Entity<Person>()
.HasIndex(p => p.Name)
.IsUnique();
// multi column index
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.Name, p.Firstname })
.IsUnique();
También es posible marcar el índice como agrupado con .IsClustered()
.
EDITAR # 1
Se agregó un ejemplo de índice de varias columnas e información adicional sobre cómo marcar un índice como agrupado.
EDITAR # 2
Como información adicional, en EF Core 2.1 es exactamente igual que en EF 6.2 ahora.
Aquí está el artículo de MS Doc como referencia.
new
. Yo lo arreglare.
Actualmente no existe un "soporte de primera clase" para crear un índice a través de la API fluida, pero lo que puede hacer es a través de la API fluida que puede marcar propiedades como atributos de la API de anotaciones. Esto le permitirá agregar el Index
atributo a través de una interfaz fluida.
A continuación, se muestran algunos ejemplos del elemento de trabajo del sitio de problemas para EF.
Cree un índice en una sola columna:
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute()));
Varios índices en una sola columna:
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new[]
{
new IndexAttribute("Index1"),
new IndexAttribute("Index2") { IsUnique = true }
}));
Índices de varias columnas:
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty1)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("MyIndex", 1)));
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty2)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("MyIndex", 2)));
El uso de las técnicas anteriores hará que las .CreateIndex()
llamadas se creen automáticamente para usted en su Up()
función cuando realice el scaffolding de su próxima migración (o se crearán automáticamente en la base de datos si no está usando migraciones).
.Primarykey(x=>x.id,clustered:false)
método
HasAnnotation
método y NO hay un método como este. pero encontré un método cuyo nombre HasColumnAnnotation
acepta los parámetros que proporcionas. ¿Necesitas actualizar tu respuesta o me equivoco?
Creé algunos métodos de extensión y los envolví en un paquete nuget para hacer esto mucho más fácil.
Instale el EntityFramework.IndexingExtensions
paquete nuget.
Entonces puedes hacer lo siguiente:
public class MyDataContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasIndex("IX_Customers_Name", // Provide the index name.
e => e.Property(x => x.LastName), // Specify at least one column.
e => e.Property(x => x.FirstName)) // Multiple columns as desired.
.HasIndex("IX_Customers_EmailAddress", // Supports fluent chaining for more indexes.
IndexOptions.Unique, // Supports flags for unique and clustered.
e => e.Property(x => x.EmailAddress));
}
}
El proyecto y el código fuente están aquí . ¡Disfrutar!
IndexAttribute
clase de EF , por lo que no puedo incluirlo en mi biblioteca.
Sin un nombre explícito:
[Index]
public int Rating { get; set; }
Con un nombre específico:
[Index("PostRatingIndex")]
public int Rating { get; set; }
EntityFramework
. está incluido en ese ensamblaje. simplemente confundido acerca de la NS.
instead of using the new IndexAttribute
¿lo notó?
A partir de EF 6.1, [Index]
se admite el atributo .
Utilizar [Index(IsUnique = true)]
para índice único.
Aquí está el enlace de Microsoft
public class User
{
public int UserId { get; set; }
[Index(IsUnique = true)]
[StringLength(200)]
public string Username { get; set; }
public string DisplayName { get; set; }
}
[Index("IX_BlogIdAndRating", 2)]
public int Rating { get; set; }
[Index("IX_BlogIdAndRating", 1)]
public int BlogId { get; set; }
aquí la referencia de Microsoft
Entity Framework 6
Property(c => c.MyColumn)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_MyIndex")));
Y agregue usando:
using System.Data.Entity.Infrastructure.Annotations;
using System.ComponentModel.DataAnnotations.Schema;
Puede utilizar la anotación de datos INDEX Code First Data Annotations
Si no desea utilizar atributos en sus POCO, siempre puede hacerlo de la siguiente manera:
context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ...");
Puede ejecutar esta declaración en su DbInitializer
clase derivada personalizada . Sin embargo, no conozco ninguna forma de Fluent API de hacer esto.
Escribo un método de extensión para usarlo en EF fluido para evitar código adicional:
public static PrimitivePropertyConfiguration HasIndexAnnotation(
this PrimitivePropertyConfiguration primitivePropertyConfiguration,
IndexAttribute indexAttribute = null
)
{
indexAttribute = indexAttribute ?? new IndexAttribute();
return primitivePropertyConfiguration
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(indexAttribute)
);
}
luego úsalo así:
Property(t => t.CardNo)
.HasIndexAnnotation();
o así si el índice necesita algunas configuraciones:
Property(t => t.CardNo)
.HasIndexAnnotation(new IndexAttribute("IX_Account") { IsUnique = true });
Puedes usar uno de estos
// Índices
this.HasIndex(e => e.IsActive)
.HasName("IX_IsActive");
o
this.Property(e => e.IsActive).HasColumnAnnotation(
"Index",
new IndexAnnotation(new IndexAttribute("IX_IsActive")));