using System; using System.Collections.Generic; using System.Text; namespace Apewer.Source { /// <summary>表示此表拥有索引,此特性不被继承。</summary> [Serializable] [AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)] public sealed class IndexAttribute : Attribute { string _name = null; string _sql = null; /// <summary>索引名称。</summary> public string Name { get; } /// <summary>用于创建索引的 SQL 语句。</summary> public string SqlStatement { get; set; } /// <summary>声明索引。</summary> /// <param name="name">索引名称。</param> /// <param name="sqlStatement">用于创建此索引的 SQL 语句。</param> public IndexAttribute(string name, string sqlStatement) { _name = name.ToTrim(); _sql = sqlStatement.ToTrim(); } /// <summary>从 <see cref="IndexAttribute"/> 到 Boolean 的隐式转换,判断 <see cref="IndexAttribute"/> 有效。</summary> public static implicit operator bool(IndexAttribute instance) { if (instance == null) return false; if (instance._name.IsEmpty()) return false; if (instance._sql.IsEmpty()) return false; return true; } #region Parse & Cache private static Dictionary<string, IndexAttribute[]> _cache = new Dictionary<string, IndexAttribute[]>(); /// <summary>解析索引特性,默认使用缓存以提升性能。</summary> public static IndexAttribute[] Parse<T>(bool useCache = true) where T : class, new() => Parse(typeof(T), useCache); /// <summary>解析索引特性,默认使用缓存以提升性能。</summary> public static IndexAttribute[] Parse(Type type, bool useCache = true) { if (type == null) return new IndexAttribute[0]; var cacheKey = type.FullName; if (useCache) { lock (_cache) { IndexAttribute[] cached; if (_cache.TryGetValue(cacheKey, out cached)) return cached; } } var attributes = type.GetCustomAttributes(typeof(IndexAttribute), false); var list = new List<IndexAttribute>(); foreach (var attribute in attributes) { var ia = attribute as IndexAttribute; if (!ia) continue; list.Add(ia); } var items = list.ToArray(); if (useCache) { lock (_cache) { if (_cache.ContainsKey(cacheKey)) _cache[cacheKey] = items; else _cache.Add(cacheKey, items); } } return items; } #endregion } }