【问题标题】:How to make a property unique in Entity Framework Code First如何在 Entity Framework Code First 中使属性唯一
【发布时间】:2019-05-19 23:49:00
【问题描述】:

这是我的User 模型类:

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);
}

但它不起作用。任何进一步的帮助将不胜感激!

【问题讨论】:

  • 不完全是什么意思?您收到任何异常或错误消息?出乎意料的结果?您需要更具体地了解您的问题。
  • 什么也没发生。当我输入一个已经存在的用户名时,它将进入数据库并记录它
  • 尝试使用x => x.Username == UserName.ToLowerInvariant() 并告诉我它是否有效!
  • 还是什么都没发生
  • 您的UserName 也可能包含空格。也可以在ToLower方法之后尝试Trim方法,看看是否有效!

标签: c# json entity-framework linq ef-code-first


【解决方案1】:

您可以使用DataAnnotationFluentApi 来创建模型属性Unique,如下所示:

使用数据注解:

[Required]
[StringLength(30)]
[Index("Ix_UserName",Order =1,IsUnique =true)]
public string UserName { get; set; }

使用 Fluent Api:

在实体框架 >= 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();
}

在实体框架中

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 正常工作,请在UserName 属性上写下您的RemoteAttibute,如下所示:

[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>

现在一切正常!

【讨论】:

    【解决方案2】:

    RemoteAttribute 与实体框架没有任何关系。它只是忽略了这个属性。此外,正如文档所述,它是一个 jQuery 验证属性,它应该只适用于前端部分。

    如果User 既是 MVC 模型又是数据库实体,您应该为属性创建唯一索引。一种方法是使用DbContext 中的OnModelCreating 方法:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasIndex(x => new { x.Username }).IsUnique();
    }
    

    然后创建一个迁移,将它应用到数据库中,你就可以开始了。但是,请注意保存副本时会出现异常,并确保正确处理。

    【讨论】:

      【解决方案3】:

      我在 HomeController 中创建了一个方法

         public bool IsUserExist(string email)
         {
              return db.Users.Where(c => c.Email == email).IsAny();
         } 
      

      在行动中

          if( IsUserExist(model.Email) )
          {
              // my code
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-18
        • 1970-01-01
        • 2011-12-24
        • 2012-05-10
        • 2012-08-09
        • 2017-05-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多