我正在使用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之外的数据库中添加唯一索引是最好的方法吗?
答案 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