2011-07-18 63 views
6

我正在使用Entity Framework Code First和SqlCe4編寫一個ASP.net MVC3應用程序。EFCodeFirst和SqlCe4的唯一約束條件

我一直在設計幾個模型,並發現一個是有趣的。這是我到目前爲止有:

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

我然而,需要一個唯一約束或索引,因爲對於一個特定的學生,我想他們必須有偏好的列表,但PresentationId需要是唯一的爲每個學生。有沒有辦法通過Code First或某些驗證屬性來完成此操作?

這聽起來像我正在沿着偏好對象作爲媒介的多對多關係的分支,以添加Rank屬性。但是,我似乎無法找到如何確保這些值是唯一的。真的是最好的方法來手動添加一個唯一的索引到EF以外的數據庫?

回答

0

什麼Eranga在說下去,我最終使它同樣的工作,但這樣的:

我曾經在我的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; } 
} 

在數據庫初始化器類,我用下面的:

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

當前(即EF 4.1)EF沒有Attribute或配置機制來創建唯一索引。

但是,如果您使用的是數據庫初始化程序,你可以手動創建

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

或者執行它初始化之外。

+0

: 'Database.SetInitializer (新DropCreateDatabaseIfModelChanges ());' 然而,在試圖實現您的解決方案,它無法在含ModelMatchesDatabase行編譯() – mandreko

+1

這個答案適用於我,目前在我的生產版本 – Yablargo

1

我不確定該功能存在多久,但在EF5中,可以在Up()和Down()方法中使用CreateIndex和DropIndex方法。這使您可以使用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"); 
    } 
} 

真正的,見上面,是指定它是唯一約束的參數。令人遺憾的是,這些限制在稍後進行進一步的遷移時並未得到遵守(如果您更改底層模式,EF不會爲您放棄這些限制),但我希望通過使用EF API,您的代碼可以免費升級這個功能最終被添加。

目前我用的是內置的初始化