实体框架代码中的唯一约束

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (35)

问题

是否可以使用FLUENT语法或属性对属性定义唯一约束?如果没有,有什么解决办法?

我有一个具有主键的用户类,但我想确保电子邮件地址也是唯一的。如果不直接编辑数据库,这是可能的吗?

解决方案(基于Matt的回答)

public class MyContext : DbContext {
    public DbSet<User> Users { get; set; }

    public override int SaveChanges() {
        foreach (var item in ChangeTracker.Entries<IModel>())
            item.Entity.Modified = DateTime.Now;

        return base.SaveChanges();
    }

    public class Initializer : IDatabaseInitializer<MyContext> {
        public void InitializeDatabase(MyContext context) {
            if (context.Database.Exists() && !context.Database.CompatibleWithModel(false))
                context.Database.Delete();

            if (!context.Database.Exists()) {
                context.Database.Create();
                context.Database.ExecuteSqlCommand("alter table Users add constraint UniqueUserEmail unique (Email)");
            }
        }
    }
}
提问于
用户回答回答于

据我所知,目前还无法用实体框架来实现这一点。但是,这不仅仅是一个具有唯一约束的问题,可能希望创建索引、检查约束,可能还需要触发器和其他构造。代码第一设置中,必须承认,它并不是与数据库无关的:

public class MyRepository : DbContext {
    public DbSet<Whatever> Whatevers { get; set; }

    public class Initializer : IDatabaseInitializer<MyRepository> {
        public void InitializeDatabase(MyRepository context) {
            if (!context.Database.Exists() || !context.Database.ModelMatchesDatabase()) {
                context.Database.DeleteIfExists();
                context.Database.Create();

                context.ObjectContext.ExecuteStoreCommand("CREATE UNIQUE CONSTRAINT...");
                context.ObjectContext.ExecuteStoreCommand("CREATE INDEX...");
                context.ObjectContext.ExecuteStoreCommand("ETC...");
            }
        }
    }
}

另一种选择是,如果域模型是在数据库中插入/更新数据的唯一方法,则可以自己实现唯一性要求,并将数据库排除在外。这是一种更可移植的解决方案,迫使在代码中清楚地了解业务规则,但却使数据库对无效的数据开放。

用户回答回答于

从EF 6.1开始,现在有可能:

[Index(IsUnique = true)]
public string EmailAddress { get; set; }

严格地说,这将给一个唯一的索引,而不是唯一的约束。

扫码关注云+社区