2013-05-31 12 views
9

Say mam następujący model:Tworzenie indeksu bazy danych z 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; } 
} 

Czy jest możliwe aby dodać indeks na kolumnie IMEI dzięki użyciu atrybutu, adnotacji danych, czy coś z tego modelu?

Odpowiedz

11

Zgodnie z tym linkiem: Creating Indexes via Data Annotations with Entity Framework 5.0 trzeba napisać jakiś kod rozszerzenia:

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

i drugą klasę:

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

po niej można użyć twój index ten sposób:

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

Czego potrzebujesz, aby móc korzystać z "indeksu"? Jeśli spróbuję użyć tego '[Index (" IMEIIndex ", unique: true)], prosi mnie o wygenerowanie mojej własnej klasy Index – Pete

+0

@Pete - zaktualizowałem moją odpowiedź - pierwsza wersja nie była kompletna. – MikroDel

+0

Bardzo miło, wydaje się, że mi się udało. Dzięki! Dam ci nagrodę, gdy ta strona mi pozwoli (muszę czekać najwyżej godzinę) – Pete

14

UPDATE: Od wydania EF 6.1. (17 marca 2014 r.) Rzeczywiście dostępny jest atrybut [Index].

Funkcjonalność jak:

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

wychodzi z pudełka.

PS: inne właściwości to Order i IsClustered.


Według tego linku: http://blogs.msdn.com/b/adonet/archive/2014/02/11/ef-6-1-0-beta-1-available.aspx

Będzie on dostępny w EF 6.1 jako standardowy atrybut DataAnnotation.

Funkcja IndexAttribute umożliwia określenie indeksów poprzez umieszczenie atrybutu [Index] we właściwości (lub właściwościach) w pierwszym modelu kodu. Kod Najpierw utworzymy odpowiedni indeks w bazie danych.

+1

Dzięki. Tylko uwaga: musisz dodać odwołanie EntityFramework w projekcie, w którym chcesz go użyć. A System.ComponentModel.DataAnnotations to za mało. Trochę mi zaszkodziło, abym zrozumiał. – Andrew

+2

Aby być uczciwym, obecny stan EF 6.x ma drugi parametr "IsUnique = true/false". –

+0

@ClaudioLudovicoPanetta: dobra rada, naprawię to. – Stefan

Powiązane problemy