2013-05-31 28 views
9

Dire che ho il seguente modello:Crea indice di database con Entity Framework

[Table("Record")] 
public class RecordModel 
{ 
    [Key] 
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 
    [Display(Name = "Record Id")] 
    public int RecordId { get; set; } 

    [StringLength(150)] 
    public string Name { get; set; } 

    [Required] 
    [StringLength(15)] 
    public string IMEI { get; set; } 
} 

E 'possibile aggiungere un indice alla colonna IMEI attraverso l'utilizzo di un attributo, l'annotazione di dati, o qualcosa dal modello?

risposta

11

Secondo questo link: Creating Indexes via Data Annotations with Entity Framework 5.0 si dovrebbe scrivere una sorta di codice di estensione:

using System; 

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)] 
public class IndexAttribute : Attribute 
{ 
    public IndexAttribute(string name, bool unique = false) 
    { 
     this.Name = name; 
     this.IsUnique = unique; 
    } 

    public string Name { get; private set; } 

    public bool IsUnique { get; private set; } 
} 

e la seconda classe:

using System.ComponentModel.DataAnnotations.Schema; 
using System.Data.Entity; 
using System.Linq; 
using System.Reflection; 

public class IndexInitializer<T> : IDatabaseInitializer<T> where T : DbContext 
{ 
    private const string CreateIndexQueryTemplate = "CREATE {unique} INDEX {indexName} ON {tableName} ({columnName})"; 

    public void InitializeDatabase(T context) 
    { 
     const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance; 

     foreach (var dataSetProperty in typeof(T).GetProperties(PublicInstance).Where(
      p => p.PropertyType.Name == typeof(DbSet<>).Name)) 
     { 
      var entityType = dataSetProperty.PropertyType.GetGenericArguments().Single(); 

      TableAttribute[] tableAttributes = (TableAttribute[])entityType.GetCustomAttributes(typeof(TableAttribute), false); 

      foreach (var property in entityType.GetProperties(PublicInstance)) 
      { 
       IndexAttribute[] indexAttributes = (IndexAttribute[])property.GetCustomAttributes(typeof(IndexAttribute), false); 
       NotMappedAttribute[] notMappedAttributes = (NotMappedAttribute[])property.GetCustomAttributes(typeof(NotMappedAttribute), false); 
       if (indexAttributes.Length > 0 && notMappedAttributes.Length == 0) 
       { 
        ColumnAttribute[] columnAttributes = (ColumnAttribute[])property.GetCustomAttributes(typeof(ColumnAttribute), false); 

        foreach (var indexAttribute in indexAttributes) 
        { 
         string indexName = indexAttribute.Name; 
         string tableName = tableAttributes.Length != 0 ? tableAttributes[0].Name : dataSetProperty.Name; 
         string columnName = columnAttributes.Length != 0 ? columnAttributes[0].Name : property.Name; 
         string query = CreateIndexQueryTemplate.Replace("{indexName}", indexName) 
          .Replace("{tableName}", tableName) 
          .Replace("{columnName}", columnName) 
          .Replace("{unique}", indexAttribute.IsUnique ? "UNIQUE" : string.Empty); 

         context.Database.CreateIfNotExists(); 

         context.Database.ExecuteSqlCommand(query); 
        } 
       } 
      } 
     } 
    } 
} 

Dopo che è possibile utilizzare il index in questo modo:

[Required] 
[Index("IMEIIndex", unique: true)] 
[StringLength(15)] 
public string IMEI { get; set; } 
+0

Cosa si deve usare per poter usare l'indice? Se provo a usare questo '[Index (" IMEIIndex ", unique: true)]' mi chiede di generare la mia propria classe Index – Pete

+0

@Pete - ha aggiornato la mia risposta - la prima versione non era completa. – MikroDel

+0

Molto bello, sembra aver fatto il trucco per me. Grazie! Ti darò la taglia quando questo sito mi permetterà (devo aspettare 1 ora apparentemente) – Pete

14

UPDATE: Dalla versione di EF 6.1. (17 marzo 2014) esiste effettivamente un attributo [Index] disponibile.

funzionalità:

[Index("IMEIIndex", IsUnique = true)] 
public string IMEI { get; set; } 

esce dalla scatola.

PS: altre proprietà sono Order e IsClustered.


Secondo questo link: http://blogs.msdn.com/b/adonet/archive/2014/02/11/ef-6-1-0-beta-1-available.aspx

Sarà disponibile in EF 6.1 come attributo DataAnnotation standard.

IndexAttribute consente di specificare gli indici posizionando un attributo [Indice] su una proprietà (o proprietà) nel proprio modello Code First. Code First creerà quindi un indice corrispondente nel database.

+1

Grazie. Solo una nota: è necessario aggiungere un riferimento a EntityFramework nel progetto in cui si desidera utilizzare questo. Un System.ComponentModel.DataAnnotations non è sufficiente. Ho preso un po 'per me per capire. – Andrew

+2

Per essere corretti, lo stato corrente di EF 6.x ha "IsUnique = true/false" come secondo parametro. –

+0

@ClaudioLudovicoPanetta: buon punto, lo aggiusterò. – Stefan

Problemi correlati