2011-07-18 10 views
6

Piszę aplikację ASP.net MVC3 przy użyciu Entity Framework Code First i SqlCe4.Unikalne ograniczenie z EFCodeFirst i SqlCe4

Projektowałem kilka modeli i znalazłem taki, który okazuje się interesujący. To, co mam tak daleko:

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

ja jednak potrzebne ograniczenie przez unikalność lub indeksu, ponieważ dla danego studenta, chcę je mieć listę preferencji, ale PresentationId musi być unikalny dla każdego ucznia. Czy istnieje sposób, aby to zrobić przez Code First lub jakiś atrybut sprawdzania poprawności?

Wygląda na to, że wchodzę w gałąź od wielu do wielu relacji z obiektem Preferencji będącym pośrednikiem, aby dodać właściwość Rank. Jednak nie mogę znaleźć sposobu, aby upewnić się, że wartości są unikalne. Czy najlepszym rozwiązaniem jest ręczne dodanie unikalnego indeksu do bazy danych poza EF?

Odpowiedz

0

Przechodzenie z co Eranga mówił, skończyło się na co działa podobnie, ale tak:

Użyłem następujący kod w mojej klasie 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; } 
} 

w bazie klasy inicjująca, użyłem następujących czynności:

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

Obecnie (tj. EF 4.1) EF nie posiada ani Attribute ani mechanizmu konfiguracyjnego do tworzenia unikatowych indeksów.

Jednak jeśli używasz bazy Initializer można utworzyć go ręcznie

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

lub wykonać ją na zewnątrz inicjatora.

+0

ja obecnie za pomocą wbudowanego inicjatora: 'Database.SetInitializer (nowe DropCreateDatabaseIfModelChanges ());' Jednak próbując wdrożyć rozwiązanie, to nie skompilować w wierszu zawierającym ModelMatchesDatabase() – mandreko

+1

Ta odpowiedź sprawdziła się i jest obecnie w mojej wersji produkcyjnej – Yablargo

1

Nie jestem pewien, jak długo ta funkcja istnieje, ale w EF5 można użyć metody CreateIndex i DropIndex w metodach Up() i Down(). Umożliwia to tworzenie unikatowych indeksów, które funkcjonują niemal identycznie jak unikalne ograniczenia, w własnym języku 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"); 
    } 
} 

Prawda, widziana powyżej, to parametr, który określa, że ​​jest to wyjątkowe ograniczenie. Niestety, ograniczenia te nie są honorowane podczas późniejszych migracji (EF nie upuszcza ich dla ciebie, jeśli zmienisz podstawowy schemat), ale mam nadzieję, że za pomocą EF API twój kod dostanie uaktualnienie za darmo, gdy ta funkcja została ostatecznie dodana.

Powiązane problemy