c# - 使用数据注释的唯一索引

标签 c# entity-framework ef-code-first indexing data-annotations

<分区>

有没有办法使用数据注释来定义唯一索引?

假设我有一个类:

public class User 
{
   [Key]
   public int UserID { get; set; }
   public string UserName { get; set; }
   public string Email { get; set; }
}

如果我希望电子邮件是唯一的,我该如何为其添加唯一索引?

最佳答案

这与我已经回答过的问题很接近 MVC Model - create db index

根据此链接:Creating Indexes via Data Annotations with Entity Framework 5.0 你应该写一些扩展代码:

using System; 

[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public class IndexAttribute : Attribute
{
    public IndexAttribute(string name, bool unique = false)
    {
        this.Name = name;
        this.IsUnique = unique;
    }

    public string Name { get; private set; }

    public bool IsUnique { get; private set; }
}

第二类:

using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Reflection;

public class IndexInitializer<T> : IDatabaseInitializer<T> where T : DbContext
{
    private const string CreateIndexQueryTemplate = "CREATE {unique} INDEX {indexName} ON {tableName} ({columnName})";

    public void InitializeDatabase(T context)
    {
        const BindingFlags PublicInstance = BindingFlags.Public | BindingFlags.Instance;

        foreach (var dataSetProperty in typeof(T).GetProperties(PublicInstance).Where(
            p => p.PropertyType.Name == typeof(DbSet<>).Name))
        {
            var entityType = dataSetProperty.PropertyType.GetGenericArguments().Single();

            TableAttribute[] tableAttributes = (TableAttribute[])entityType.GetCustomAttributes(typeof(TableAttribute), false);

            foreach (var property in entityType.GetProperties(PublicInstance))
            {
                IndexAttribute[] indexAttributes = (IndexAttribute[])property.GetCustomAttributes(typeof(IndexAttribute), false);
                NotMappedAttribute[] notMappedAttributes = (NotMappedAttribute[])property.GetCustomAttributes(typeof(NotMappedAttribute), false);
                if (indexAttributes.Length > 0 && notMappedAttributes.Length == 0)
                {
                    ColumnAttribute[] columnAttributes = (ColumnAttribute[])property.GetCustomAttributes(typeof(ColumnAttribute), false);

                    foreach (var indexAttribute in indexAttributes)
                    {
                        string indexName = indexAttribute.Name;
                        string tableName = tableAttributes.Length != 0 ? tableAttributes[0].Name : dataSetProperty.Name;
                        string columnName = columnAttributes.Length != 0 ? columnAttributes[0].Name : property.Name;
                        string query = CreateIndexQueryTemplate.Replace("{indexName}", indexName)
                            .Replace("{tableName}", tableName)
                            .Replace("{columnName}", columnName)
                            .Replace("{unique}", indexAttribute.IsUnique ? "UNIQUE" : string.Empty);

                        context.Database.CreateIfNotExists();

                        context.Database.ExecuteSqlCommand(query);
                    }
                }
            }
        }
    }
}

之后你可以这样使用你的index:

[Required]
[Index("IMEIIndex", unique: true)]
[StringLength(15)]
public string IMEI { get; set; }

关于c# - 使用数据注释的唯一索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19023958/

相关文章:

entity-framework - 是否可以在EF实体中嵌入对象(在保存时序列化,在访问时反序列化)?

c# - 在 C# 中将属性设置为静态是否有任何问题(在多访问的情况下)

c# - 关于列表排序和委托(delegate)和 lambda 表达式 Func 的东西

c# - 在 Entity Framework 中使用唯一约束交换值

sql-server - 数据库性能提升结构设计

c# - EDF 4.1 代码优先的接口(interface)和多重约束违规

c# - dotnet 核心 Entity Framework 连接已关闭

c# - 适用于 LinkedIn 的 C# SDK

asp.net - 无法在 Entity Framework 中加载一种或多种请求的类型

c# - 从字符串构建表达式<Func<T,bool>>