You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.9 KiB

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