2011-07-18 10 views
6

Estoy escribiendo una aplicación ASP.NET MVC3 utilizando Entity Framework Code First y SqlCe4.Restricción exclusiva con EFCodeFirst y SqlCe4

He estado diseñando varios modelos, y encontré uno que está resultando ser interesante. Esto es lo que tengo hasta ahora:

public class Preference 
    { 
     public int PreferenceId { get; set; } 

     [Required] 
     public int StudentId { get; set; } 
     public virtual Student Student { get; set; } 

     [Required] 
     public int PresentationId { get; set; } 
     public virtual Presentation Presentation { get; set; } 

     [Required] 
     public int Rank { get; set; } 
    } 

que sin embargo, necesitan una restricción única o un índice, ya que para un estudiante en particular, quiero que tiene que tener una lista de preferencias, pero la PresentationId debe ser único para cada estudiante ¿Hay alguna forma de hacerlo mediante Code First o algún atributo de validación?

Esto suena como que voy por la rama de una relación de muchos a muchos con el objeto de preferencia que es un intermediario, para agregar la propiedad de rango. Sin embargo, parece que no puedo encontrar la manera de asegurarme de que los valores sean únicos. ¿Es la mejor manera de agregar manualmente un índice único a la base de datos fuera de EF?

Respuesta

0

Ir con lo Eranga estaba diciendo, que terminó por hacer que funcione de manera similar, pero como esto:

que utiliza el código siguiente en mi clase DataContext:

public class StudentRegistrationContext : DbContext 
{ 
    public StudentRegistrationContext() 
    { 
     Database.SetInitializer(new StudentRegistrationDatabaseInitializer()); 
    } 

    public DbSet<Student> Students { get; set; } 
    public DbSet<Teacher> Teachers { get; set; } 
    public DbSet<Presenter> Presenters { get; set; } 
    public DbSet<Presentation> Presentations { get; set; } 
} 

En la clase inicializador base de datos, he utilizado el siguiente:

public class StudentRegistrationDatabaseInitializer : DropCreateDatabaseIfModelChanges<StudentRegistrationContext> 
{ 
    protected override void Seed(StudentRegistrationContext context) 
    { 
     base.Seed(context); 
     context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX UX_Preferences_StudentId_PresentationId ON Preferences (StudentId, PresentationId)"); 
    } 
} 
3

Actualmente (es decir, EF 4.1) EF no tiene un Attribute o mecanismo de configuración para crear índices únicos.

Sin embargo, si está utilizando la base de datos inicializador puede crear manualmente

public class MyInitializer : IDatabaseInitializer<MyContext> 
{ 
    public void InitializeDatabase(MyContext context) 
    { 
     if (!context.Database.Exists() || !context.Database.ModelMatchesDatabase()) 
     { 
      context.Database.DeleteIfExists(); 
      context.Database.Create(); 

      context.ObjectContext.ExecuteStoreCommand("CREATE INDEX IX_Preference_PresentationId ON Preference (PresentationId)"); 
     } 
    } 
} 

O ejecutarlo fuera del inicializador.

+0

momento yo estaba usando el construido en el inicializador: 'Database.SetInitializer <> (StudentRegistrationContext nuevos DropCreateDatabaseIfModelChanges <> StudentRegistrationContext());' Sin embargo, al tratar de implementar su solución, que falla al compilar en la línea que contiene ModelMatchesDatabase() – mandreko

+1

Esta respuesta funcionó para mí y actualmente está en mi versión de producción – Yablargo

1

No estoy seguro de cuánto tiempo ha existido la función, pero en EF5, puede utilizar el método CreateIndex y DropIndex en los métodos Arriba() y Abajo(). Esto le permite crear índices únicos, que funcionan de manera casi idéntica a las limitaciones únicas, en el propio lenguaje de EF.

public partial class UniqueIndexMigration 
{ 
    public override void Up() 
    { 
     // Create new unique index 
     this.CreateIndex("dbo.TableName", new[] { "Col1", "Col2", "Col3" }, true, "IX_TableName_Col1_Col2_Col3"); 
    } 

    public override void Down() 
    { 
     // Drop unique index 
     this.DropIndex("dbo.TableName", "IX_TableName_Col1_Col2_Col3"); 
    } 
} 

El verdadero, visto anteriormente, es el parámetro que especifica que es una restricción única. Lamentablemente, estas limitaciones no se respetan al realizar más migraciones más adelante (EF no las dejará para ti si cambias el esquema subyacente), pero mi esperanza es que al usar la EF API, tu código obtenga una actualización de forma gratuita cuando esta característica finalmente se agrega.

Cuestiones relacionadas