update TWA Management v0.0.1
This commit is contained in:
@ -1,4 +1,6 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
@ -7,10 +9,12 @@ namespace TWASys_App.Dapper.AExtentions
|
||||
public class PropertiesCache
|
||||
{
|
||||
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> KeyProperties = new();
|
||||
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> FKProperties = new();
|
||||
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> TypeProperties = new();
|
||||
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IEnumerable<PropertyInfo>> ComputedProperties = new();
|
||||
private static readonly ConcurrentDictionary<RuntimeTypeHandle, IReadOnlyDictionary<string, string>> ColumnNames = new();
|
||||
|
||||
|
||||
public static List<PropertyInfo> TypePropertiesCache(Type type)
|
||||
{
|
||||
if (TypeProperties.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||
@ -60,6 +64,28 @@ namespace TWASys_App.Dapper.AExtentions
|
||||
return result;
|
||||
}
|
||||
|
||||
public static bool IsPkAutoIncrement(PropertyInfo p)
|
||||
{
|
||||
|
||||
// ===== Fallback by-name (nếu không thể tham chiếu typed)
|
||||
var attrs = p.GetCustomAttributes(true);
|
||||
bool hasKeyByName = attrs.Any(a => a.GetType().Name is "KeyAttribute");
|
||||
|
||||
var dbgenByName = attrs.FirstOrDefault(a => a.GetType().Name is "DatabaseGeneratedAttribute");
|
||||
bool isIdentityByName = false;
|
||||
if (dbgenByName != null)
|
||||
{
|
||||
// Tìm property "DatabaseGeneratedOption" (enum) và đọc giá trị "Identity"
|
||||
var prop = dbgenByName.GetType().GetProperty("DatabaseGeneratedOption");
|
||||
var val = prop?.GetValue(dbgenByName)?.ToString(); // ví dụ "Identity"
|
||||
isIdentityByName = string.Equals(val, "Identity", StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
if (hasKeyByName && isIdentityByName) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<PropertyInfo> KeyPropertiesCache(Type type)
|
||||
{
|
||||
if (KeyProperties.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||
@ -68,19 +94,42 @@ namespace TWASys_App.Dapper.AExtentions
|
||||
}
|
||||
|
||||
var allProperties = TypePropertiesCache(type);
|
||||
var keyProperties = allProperties.Where(p => p.GetCustomAttributes(true).Any(a => a.GetType().Name == "KeyAttribute")).ToList();
|
||||
var keyProperties = allProperties.Where(IsPkAutoIncrement).ToList();
|
||||
KeyProperties[type.TypeHandle] = keyProperties; // ghi cache khi miss
|
||||
return keyProperties;
|
||||
}
|
||||
|
||||
if (keyProperties.Count == 0)
|
||||
|
||||
public static List<PropertyInfo> FKPropertiesCache(Type type)
|
||||
{
|
||||
if (FKProperties.TryGetValue(type.TypeHandle, out var cachedProps))
|
||||
{
|
||||
var idProp = allProperties.Find(p => string.Equals(p.Name, "id", StringComparison.CurrentCultureIgnoreCase));
|
||||
if (idProp != null)
|
||||
return cachedProps.ToList();
|
||||
}
|
||||
var allProperties = TypePropertiesCache(type);
|
||||
var keyProperties = allProperties.Where(HasForeignKeyAttribute).ToList();
|
||||
FKProperties[type.TypeHandle] = keyProperties;
|
||||
return keyProperties;
|
||||
}
|
||||
static bool HasForeignKeyAttribute(PropertyInfo p)
|
||||
{
|
||||
if (p.GetCustomAttribute<ForeignKeyAttribute>() != null) return true;
|
||||
|
||||
// FK đặt trên navigation và chỉ ra tên prop FK
|
||||
var t = p.DeclaringType!;
|
||||
foreach (var nav in t.GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
|
||||
// Fallback by-name nếu không tham chiếu DataAnnotations (tùy dự án)
|
||||
var attr = nav.GetCustomAttributes(true).FirstOrDefault(a => a.GetType().Name == "ForeignKeyAttribute");
|
||||
if (attr != null)
|
||||
{
|
||||
keyProperties.Add(idProp);
|
||||
var val = attr.GetType().GetProperty("Name")?.GetValue(attr);
|
||||
if (val == null && string.IsNullOrWhiteSpace(val?.ToString()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
KeyProperties[type.TypeHandle] = keyProperties;
|
||||
return keyProperties;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static List<PropertyInfo> ComputedPropertiesCache(Type type)
|
||||
@ -95,7 +144,7 @@ namespace TWASys_App.Dapper.AExtentions
|
||||
return computedProperties;
|
||||
}
|
||||
|
||||
private static IReadOnlyDictionary<string, string> GetColumnNames(IEnumerable<PropertyInfo> props)
|
||||
public static IReadOnlyDictionary<string, string> GetColumnNames(IEnumerable<PropertyInfo> props)
|
||||
{
|
||||
var ret = new Dictionary<string, string>();
|
||||
foreach (var prop in props)
|
||||
|
||||
Reference in New Issue
Block a user