如何使 属性 在 Entity Framework Code First 中唯一
How to make a property unique in Entity Framework Code First
这是我的 User
模型 Class:
public class User
{
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string FullName { get; set; }
[Required]
[MaxLength(30)]
[Remote("IsUsernameExists", "Home", HttpMethod = "Post")]
public string UserName { get; set; }
[Required]
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$"]
public string Email { get; set; }
[Required]
[StringLength(maximumLength: 18, MinimumLength = 8)]
public string Password { get; set; }
}
这是 Home
控制器中的 IsUsernameExists
方法
public JsonResult IsUsernameExists(string UserName)
{
return Json(!db.Users.Any(x => x.Username == UserName), JsonRequestBehavior.AllowGet);
}
但是没用。任何进一步的帮助将不胜感激!
RemoteAttribute 与 Entity Framework 没有任何关系。它只是忽略了这个属性。此外,正如文档所说,它是一个 jQuery
验证属性,它应该只在前端部分工作。
如果 User
既是 MVC 模型又是数据库实体,您应该为 属性 创建一个唯一索引。一种方法是在 DbContext
:
中的 OnModelCreating
方法中
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasIndex(x => new { x.Username }).IsUnique();
}
然后创建一个迁移,将其应用到数据库,然后就可以开始了。但是,请注意保存重复项时会遇到的异常,并确保正确处理它。
您可以使用 DataAnnotation
和 FluentApi
制作模型 属性 Unique
,如下所示:
使用数据注释:
[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
public string UserName { get; set; }
使用流利 Api:
在Entity Framework>=6.2,
在DbContext
中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().Property(u => u.UserName).HasMaxLength(30);
modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();
}
在Entity Framework < 6.2
在DbContext
中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().Property(t => t.UserName).HasMaxLength(30)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("Ix_UserName"){IsUnique = true}));
}
记住: 使用 Index
属性,您还必须使用 StringLength
属性。
为了使 RemoteAttibute
正常工作,请将您的 RemoteAttibute
写在 UserName
属性 上,如下所示:
[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
[Remote("IsUserNameExist", "Home", AdditionalFields = "Id", ErrorMessage = "User Name already exists")]
public string UserName { get; set; }
然后HomeController
中的IsUserNameExist
方法如下:
public JsonResult IsUserNameExist(string UserName, int? Id)
{
var IsUserNameExists = db.Users.Any(x => x.UserName== UserName && x.Id != Id);
return Json(!IsUserNameExists, JsonRequestBehavior.AllowGet);
}
最后确保您的视图包含以下 jQuery
个文件:
<script src="~/Scripts/jquery-version.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
现在一切正常!
我在 HomeController 中创建了一个方法
public bool IsUserExist(string email)
{
return db.Users.Where(c => c.Email == email).IsAny();
}
并在行动中
if( IsUserExist(model.Email) )
{
// my code
}
这是我的 User
模型 Class:
public class User
{
public int Id { get; set; }
[Required]
[MaxLength(100)]
public string FullName { get; set; }
[Required]
[MaxLength(30)]
[Remote("IsUsernameExists", "Home", HttpMethod = "Post")]
public string UserName { get; set; }
[Required]
[RegularExpression(@"^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$"]
public string Email { get; set; }
[Required]
[StringLength(maximumLength: 18, MinimumLength = 8)]
public string Password { get; set; }
}
这是 Home
控制器中的 IsUsernameExists
方法
public JsonResult IsUsernameExists(string UserName)
{
return Json(!db.Users.Any(x => x.Username == UserName), JsonRequestBehavior.AllowGet);
}
但是没用。任何进一步的帮助将不胜感激!
RemoteAttribute 与 Entity Framework 没有任何关系。它只是忽略了这个属性。此外,正如文档所说,它是一个 jQuery
验证属性,它应该只在前端部分工作。
如果 User
既是 MVC 模型又是数据库实体,您应该为 属性 创建一个唯一索引。一种方法是在 DbContext
:
OnModelCreating
方法中
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().HasIndex(x => new { x.Username }).IsUnique();
}
然后创建一个迁移,将其应用到数据库,然后就可以开始了。但是,请注意保存重复项时会遇到的异常,并确保正确处理它。
您可以使用 DataAnnotation
和 FluentApi
制作模型 属性 Unique
,如下所示:
使用数据注释:
[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
public string UserName { get; set; }
使用流利 Api:
在Entity Framework>=6.2,
在DbContext
中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().Property(u => u.UserName).HasMaxLength(30);
modelBuilder.Entity<User>().HasIndex(u => u.UserName).IsUnique();
}
在Entity Framework < 6.2
在DbContext
中:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<User>().Property(t => t.UserName).HasMaxLength(30)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("Ix_UserName"){IsUnique = true}));
}
记住: 使用 Index
属性,您还必须使用 StringLength
属性。
为了使 RemoteAttibute
正常工作,请将您的 RemoteAttibute
写在 UserName
属性 上,如下所示:
[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
[Remote("IsUserNameExist", "Home", AdditionalFields = "Id", ErrorMessage = "User Name already exists")]
public string UserName { get; set; }
然后HomeController
中的IsUserNameExist
方法如下:
public JsonResult IsUserNameExist(string UserName, int? Id)
{
var IsUserNameExists = db.Users.Any(x => x.UserName== UserName && x.Id != Id);
return Json(!IsUserNameExists, JsonRequestBehavior.AllowGet);
}
最后确保您的视图包含以下 jQuery
个文件:
<script src="~/Scripts/jquery-version.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
现在一切正常!
我在 HomeController 中创建了一个方法
public bool IsUserExist(string email)
{
return db.Users.Where(c => c.Email == email).IsAny();
}
并在行动中
if( IsUserExist(model.Email) )
{
// my code
}