С подходом EF Code First можно реализовать поддержку уникальных ограничений на основе атрибутов, используя следующую технику.
Создать атрибут маркера
[AttributeUsage(AttributeTargets.Property)]
public class UniqueAttribute : System.Attribute { }
Отметить свойства, которыми вы хотите бытьуникальна для сущностей, например
[Unique]
public string EmailAddress { get; set; }
Создайте инициализатор базы данных или используйте существующий для создания уникальных ограничений
public class DbInitializer : IDatabaseInitializer<DbContext>
{
public void InitializeDatabase(DbContext db)
{
if (db.Database.Exists() && !db.Database.CompatibleWithModel(false))
{
db.Database.Delete();
}
if (!db.Database.Exists())
{
db.Database.Create();
CreateUniqueIndexes(db);
}
}
private static void CreateUniqueIndexes(DbContext db)
{
var props = from p in typeof(AppDbContext).GetProperties()
where p.PropertyType.IsGenericType
&& p.PropertyType.GetGenericTypeDefinition()
== typeof(DbSet<>)
select p;
foreach (var prop in props)
{
var type = prop.PropertyType.GetGenericArguments()[0];
var fields = from p in type.GetProperties()
where p.GetCustomAttributes(typeof(UniqueAttribute),
true).Any()
select p.Name;
foreach (var field in fields)
{
const string sql = "ALTER TABLE dbo.[{0}] ADD CONSTRAINT"
+ " [UK_dbo.{0}_{1}] UNIQUE ([{1}])";
var command = String.Format(sql, type.Name, field);
db.Database.ExecuteSqlCommand(command);
}
}
}
}
Установите контекст вашей базы данных для использования этого инициализатора в коде запуска (например,в main()
или Application_Start()
)
Database.SetInitializer(new DbInitializer());
Решение аналогично Mheyman, с упрощением не поддерживающих составные ключи.Для использования с EF 5.0 +.