Browse Source

增加 IndexAttribute,用于标记索引。

master
王厅 1 week ago
parent
commit
34d1af459e
  1. 17
      Apewer/Source/ColumnAttribute.cs
  2. 81
      Apewer/Source/IndexAttribute.cs
  3. 16
      Apewer/Source/Order.cs
  4. 44
      Apewer/Source/TableIndex.cs
  5. 38
      Apewer/Source/TableStructure.cs

17
Apewer/Source/ColumnAttribute.cs

@ -1,8 +1,6 @@
using Apewer.Internals; using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Text;
namespace Apewer.Source namespace Apewer.Source
{ {
@ -28,6 +26,8 @@ namespace Apewer.Source
private bool _valid = true; private bool _valid = true;
private bool _nullable = false; private bool _nullable = false;
private List<IndexAttribute> _indexes = new List<IndexAttribute>();
private void Init(string field, ColumnType type, int length) private void Init(string field, ColumnType type, int length)
{ {
_field = field; _field = field;
@ -65,6 +65,9 @@ namespace Apewer.Source
/// <summary>字段类型。</summary> /// <summary>字段类型。</summary>
public ColumnType Type { get => _type; } public ColumnType Type { get => _type; }
/// <summary>字段上的索引。</summary>
public IndexAttribute[] Indexes { get => _indexes.ToArray(); }
#region 附加 #region 附加
/// <summary>此特性有效。</summary> /// <summary>此特性有效。</summary>
@ -153,6 +156,14 @@ namespace Apewer.Source
} }
if (!ca._primarykey && RuntimeUtility.Contains<PrimaryKeyAttribute>(property)) ca._primarykey = true; if (!ca._primarykey && RuntimeUtility.Contains<PrimaryKeyAttribute>(property)) ca._primarykey = true;
// 获取索引。
var indexes = IndexAttribute.Parse(property);
foreach (var index in indexes)
{
index.SetColumn(ca);
}
ca._indexes.AddRange(indexes);
// 检查免更新特性。 // 检查免更新特性。
var nu = RuntimeUtility.GetAttribute<NoUpdateAttribute>(property, false); var nu = RuntimeUtility.GetAttribute<NoUpdateAttribute>(property, false);
if (nu) ca._noupdate = true; if (nu) ca._noupdate = true;

81
Apewer/Source/IndexAttribute.cs

@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Apewer.Source
{
/// <summary>索引。</summary>
[Serializable]
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public sealed class IndexAttribute : Attribute, IToJson
{
PropertyInfo _property = null;
ColumnAttribute _column;
string _name = null;
Order _order = Order.Ascend;
/// <summary>索引名称。</summary>
public string Name { get => _name; }
/// <summary>排序。</summary>
public Order Order { get => _order; set => _order = value; }
/// <summary>列。</summary>
public ColumnAttribute Column { get => _column; }
/// <summary>属性。</summary>
public PropertyInfo Property { get => _property; }
/// <summary>表示此属性是索引的一部分。</summary>
/// <param name="name">索引名称。</param>
public IndexAttribute(string name)
{
if (string.IsNullOrEmpty(name)) throw new ArgumentNullException(nameof(name));
_name = name;
}
internal void SetColumn(ColumnAttribute column)
{
_column = column;
}
/// <summary>解析列的索引。</summary>
/// <remarks>注意:此方法不再抛出异常,当不存在正确的列特性时将返回 NULL 值</remarks>
public static IndexAttribute[] Parse(PropertyInfo property)
{
if (property == null) return null;
var attributes = property.GetCustomAttributes(typeof(IndexAttribute), true);
var ias = new List<IndexAttribute>();
foreach (var attribute in attributes)
{
var ia = attribute as IndexAttribute;
if (ia == null) continue;
if (ia._name.IsEmpty()) continue;
ia._property = property;
ias.Add(ia);
}
return ias.ToArray();
}
/// <summary>生成 Json 对象。</summary>
/// <exception cref="NotImplementedException"></exception>
public Json ToJson()
{
var json = Json.NewObject();
json.SetProperty("name", _name);
json.SetProperty("order", _order.ToString());
if (_column != null) json.SetProperty("column", _column.ToJson());
return json;
}
/// <summary></summary>
public override string ToString() => $"Index = {_name}, Field = {_column?.Field}, Order = {_order}";
}
}

16
Apewer/Source/Order.cs

@ -0,0 +1,16 @@
namespace Apewer.Source
{
/// <summary>排序。</summary>
public enum Order
{
/// <summary>升序排序。</summary>
Ascend,
/// <summary>降序排序。</summary>
Descend
}
}

44
Apewer/Source/TableIndex.cs

@ -0,0 +1,44 @@
using System;
namespace Apewer.Source
{
/// <summary>索引。</summary>
public sealed class TableIndex
{
/// <summary>索引名称。</summary>
public string Name { get; }
/// <summary>表。</summary>
public TableAttribute Table { get; }
/// <summary>索引字段。</summary>
public IndexAttribute[] Fields { get; }
/// <summary>创建索引实例。</summary>
/// <exception cref="ArgumentNullException"></exception>
internal TableIndex(string name, TableAttribute table, IndexAttribute[] fields)
{
if (name.IsEmpty()) throw new ArgumentNullException(nameof(name));
if (table == null) throw new ArgumentNullException(nameof(table));
if (fields == null) throw new ArgumentNullException(nameof(fields));
Name = name;
Table = table;
Fields = fields;
}
/// <summary></summary>
public override string ToString()
{
var fields = Fields.FindAll(x => x != null && x.Column != null);
if (fields.IsEmpty()) return Name;
var array = fields.Map(x => x.Order == Order.Ascend ? x.Column.Field : $"{x.Column.Field} DESC");
return $"{Name} ({array.Join(", ")})";
}
}
}

38
Apewer/Source/TableStructure.cs

@ -1,10 +1,7 @@
using Apewer.Internals; using System;
using Apewer;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.Reflection; using System.Reflection;
using System.Text;
namespace Apewer.Source namespace Apewer.Source
{ {
@ -20,6 +17,7 @@ namespace Apewer.Source
TableAttribute _table = null; TableAttribute _table = null;
ColumnAttribute _key = null; ColumnAttribute _key = null;
ColumnAttribute _flag = null; ColumnAttribute _flag = null;
TableIndex[] _indexes = null;
ColumnAttribute[] _columns = null; ColumnAttribute[] _columns = null;
ColumnAttribute[] _fillable = null; ColumnAttribute[] _fillable = null;
@ -31,6 +29,9 @@ namespace Apewer.Source
/// <summary>表特性。</summary> /// <summary>表特性。</summary>
public TableAttribute Table { get => _table; } public TableAttribute Table { get => _table; }
/// <summary>索引。</summary>
public TableIndex[] Indexes { get => _indexes; }
/// <summary>列信息。</summary> /// <summary>列信息。</summary>
public ColumnAttribute[] Columns { get => _columns; } public ColumnAttribute[] Columns { get => _columns; }
@ -120,6 +121,7 @@ namespace Apewer.Source
var columns = new ColumnAttribute[total]; var columns = new ColumnAttribute[total];
var columnsCount = 0; var columnsCount = 0;
var fillable = new List<ColumnAttribute>(total); var fillable = new List<ColumnAttribute>(total);
var indexesDict = new Dictionary<string, List<IndexAttribute>>();
if (total > 0) if (total > 0)
{ {
var caForce = force || (ta ? ta.AllProperties : false); var caForce = force || (ta ? ta.AllProperties : false);
@ -151,6 +153,24 @@ namespace Apewer.Source
} }
} }
// 索引
foreach (var index in ca.Indexes)
{
var indexName = index.Name.Lower();
if (indexName.IsEmpty()) continue;
if (indexesDict.TryGetValue(indexName, out var list))
{
list.Add(index);
}
else
{
list = new List<IndexAttribute>();
list.Add(index);
indexesDict.Add(indexName, list);
}
}
// 可查询的列。 // 可查询的列。
fillable.Add(ca); fillable.Add(ca);
continue; continue;
@ -166,6 +186,15 @@ namespace Apewer.Source
} }
if (columnsCount > 0 && columnsCount != columns.Length) columns = columns.Slice(0, columnsCount); if (columnsCount > 0 && columnsCount != columns.Length) columns = columns.Slice(0, columnsCount);
// 整理索引。
var indexes = new List<TableIndex>();
foreach (var indexesList in indexesDict.Values)
{
var indexName = indexesList[0].Name;
var tableIndex = new TableIndex(indexName, ta, indexesList.ToArray());
indexes.Add(tableIndex);
}
// 排序,将 Key 和 Flag 排在最前。 // 排序,将 Key 和 Flag 排在最前。
columns = ColumnAttribute.Sort(columns); columns = ColumnAttribute.Sort(columns);
@ -174,6 +203,7 @@ namespace Apewer.Source
ts._table = ta; ts._table = ta;
ts._key = key; ts._key = key;
ts._flag = flag; ts._flag = flag;
ts._indexes = indexes.ToArray();
ts._columns = columns; ts._columns = columns;
ts._model = model; ts._model = model;
ts._fillable = fillable.ToArray(); ts._fillable = fillable.ToArray();

Loading…
Cancel
Save