EFCodeFirst和SqlCe4的唯一约束

时间:2011-07-18 00:43:55

标签: sql-server asp.net-mvc-3 ef-code-first

我正在使用Entity Framework Code First和SqlCe4编写ASP.net MVC3应用程序。

我一直在设计几个模型,并发现一个变得有趣。这就是我到目前为止所做的:

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或一些验证属性来做到这一点?

这听起来像是在Preference对象作为中间人的多对多关系的分支下,添加Rank属性。但是,我似乎无法找到如何确保值是唯一的。真正的手动只是在EF之外的数据库中添加唯一索引是最好的方法吗?

4 个答案:

答案 0 :(得分: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 )");
        }
    }
}

或者在初始化程序之外执行。

答案 1 :(得分: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,您的代码将免费升级。最后添加了这个功能。

答案 2 :(得分: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; }
}

在Database Initializer类中,我使用了以下内容:

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 :(得分:0)

请参阅使用Custom ValidationAttribute实现Unique约束的answear: https://stackoverflow.com/a/10566485/1133338