首先使用EF代码的唯一键

Pra*_*dda 62 c# unique-key ef-code-first entity-framework-4.1

我的项目中有以下模型

public class Category
{   
    public Guid ID { get; set; }
    [Required(ErrorMessage = "Title cannot be empty")]
    public string Title { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

而我正在尝试制作一个Title独特的密钥,我搜索解决方案,但找不到任何.可以建议我怎么做,拜托?

Lad*_*nka 109

遗憾的是,您无法首先将其定义为代码中的唯一键,因为EF根本不支持唯一键(希望计划用于下一个主要版本).您可以做的是创建自定义数据库intializer并通过调用SQL命令手动添加唯一索引:

public class MyInitializer : CreateDatabaseIfNotExists<MyContext>
{
  protected override void Seed(MyContext context)
  {
    context.Database.ExecuteSqlCommand("CREATE UNIQUE INDEX IX_Category_Title ON Categories (Title)");
  }
}
Run Code Online (Sandbox Code Playgroud)

您必须在应用程序的引导程序中设置此初始化程序.

Database.SetInitializer<MyContext>(new MyInitializer());
Run Code Online (Sandbox Code Playgroud)

编辑

现在(EF 6.1以后)您可以轻松拥有独特的约束,

[Index("TitleIndex", IsUnique = true)]
 public string Title { get; set; }
Run Code Online (Sandbox Code Playgroud)

  • 种子被执行多次 - 由于数据库中已经存在索引(或函数/存储过程/或其他),这不会出错吗? (2认同)

Joa*_*eme 22

首先创建自定义属性类:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class UniqueAttribute : ValidationAttribute
{
   public override Boolean IsValid(Object value)
    {
        // constraint implemented on database
        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后添加到您的课程:

public class Email
{
    [Key]
    public int EmailID { get; set; }

    public int PersonId { get; set; }

    [Unique]
    [Required]
    [MaxLength(100)]
    public string EmailAddress { get; set; }
    public virtual bool IsDefault { get; set; }
    public virtual Boolean IsApprovedForLogin { get; set; }
    public virtual String ConfirmationToken { get; set; }

    [ForeignKey("PersonId")]
    public virtual Person Person { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后在DbContext上添加一个Initializer:

public class Initializer : IDatabaseInitializer<myEntities>
{
    public void InitializeDatabase(myEntities context)
    {
        if (System.Diagnostics.Debugger.IsAttached && context.Database.Exists() && !context.Database.CompatibleWithModel(false))
        {
            context.Database.Delete();
        }

        if (!context.Database.Exists())
        {
            context.Database.Create();

            var contextObject = context as System.Object;
            var contextType = contextObject.GetType();
            var properties = contextType.GetProperties();
            System.Type t = null;
            string tableName = null;
            string fieldName = null;
            foreach (var pi in properties)
            {
                if (pi.PropertyType.IsGenericType && pi.PropertyType.Name.Contains("DbSet"))
                {
                    t = pi.PropertyType.GetGenericArguments()[0];

                    var mytableName = t.GetCustomAttributes(typeof(TableAttribute), true);
                    if (mytableName.Length > 0)
                    {
                        TableAttribute mytable = mytableName[0] as TableAttribute;
                        tableName = mytable.Name;
                    }
                    else
                    {
                        tableName = pi.Name;
                    }

                    foreach (var piEntity in t.GetProperties())
                    {
                        if (piEntity.GetCustomAttributes(typeof(UniqueAttribute), true).Length > 0)
                        {
                            fieldName = piEntity.Name;
                            context.Database.ExecuteSqlCommand("ALTER TABLE " + tableName + " ADD CONSTRAINT con_Unique_" + tableName + "_" + fieldName + " UNIQUE (" + fieldName + ")");
                        }
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

最后在Global.asax.cs中的Application_Start中添加Initializer

System.Data.Entity.Database.SetInitializer<MyApp.Models.DomainModels.myEntities>(new MyApp.Models.DomainModels.myEntities.Initializer());
Run Code Online (Sandbox Code Playgroud)

而已.基于/sf/answers/519874141/上的vb代码