Files
TWA-App/TWASys-App/Dapper.AExtentions/DapperCommand.cs

190 lines
8.0 KiB
C#

using Dapper;
using Newtonsoft.Json.Linq;
using System.Data;
using System.Data.Common;
using System.Net.WebSockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Xml.Linq;
namespace TWASys_App.Dapper.AExtentions
{
public static class DapperCommand
{
public static dynamic QueryInsert<T>(T obj)
{
return QueryInsert(obj, new Dictionary<string, DataValue>());
}
public static dynamic QueryInsert<T>(T obj, Dictionary<string, DataValue> data, int IdTable = 100)
{
var type = typeof(T);
var tableName = TableMapper.GetTableName(type);
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var fkProperties = PropertiesCache.FKPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
var columns = PropertiesCache.GetColumnNamesCache(type);
var insertProperties = allProperties.Except(computedProperties).Except(fkProperties).ToList();
var insertPropertiesString = string.Empty;
var stringKeyProperty = string.Empty;
var keyAI = string.Empty;
var flag = false;
var q = string.Empty;
if (keyProperties.Count > 0)
{
flag = true;
insertProperties = insertProperties.Except(keyProperties).ToList();
stringKeyProperty = GetColumnsString(keyProperties.ToList(), columns);
keyAI = $@"SET @{GetColumnsString(keyProperties.ToList(), columns, IdTable.ToString(), "")} := LAST_INSERT_ID();";
}
insertPropertiesString = GetColumnsString(insertProperties, columns);
var fkPropertiesString = string.Empty;
var fkValuesString = string.Empty;
if (data.Count > 0)
{
fkPropertiesString = GetColumnsString(fkProperties, columns);
fkValuesString = string.Join(", ", fkProperties.Select(u => {
var ok = data.TryGetValue(u.Name, out var v);
if (ok)
{
return $"@tb{v?.Name}_{u.Name}";
}
else
{
return $"@tb{IdTable}_{u.Name}";
}
}));
fkPropertiesString += (string.IsNullOrEmpty(fkPropertiesString))?"": ", ";
fkValuesString += (string.IsNullOrEmpty(fkValuesString)) ? "" : ", ";
}
q = $@"INSERT INTO {FormatTableName(tableName)} ({fkPropertiesString + insertPropertiesString}) VALUES ({fkValuesString + GetColumnsString(insertProperties, columns, IdTable.ToString(), "@")});
{keyAI}";
return new
{
IsKeyAI = flag,
Query = q,
Name = IdTable.ToString(),
KeyVar = stringKeyProperty
};
}
public static async Task Insert<T>(this DbConnection connection, T obj, IDbTransaction? tx = null)
{
var type = typeof(T);
var tableName = TableMapper.GetTableName(type);
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
var columns = PropertiesCache.GetColumnNamesCache(type);
var insertProperties = allProperties.Except(computedProperties).ToList();
var insertPropertiesString = string.Empty;
if (keyProperties.Count > 0)
{
insertProperties = insertProperties.Except(keyProperties).ToList();
insertPropertiesString = GetColumnsString(insertProperties, columns);
var insertedId = await connection.QueryFirstAsync<int>($@"
INSERT INTO {FormatTableName(tableName)} ({insertPropertiesString}) VALUES ({GetColumnsString(insertProperties, columns, "@")});
SELECT LAST_INSERT_ID()", obj, tx);
keyProperties[0].SetValue(obj, insertedId);
}
else
{
insertPropertiesString = GetColumnsString(insertProperties, columns);
await connection.QueryFirstAsync($@"
INSERT INTO {FormatTableName(tableName)}({insertPropertiesString})
VALUES ({GetColumnsString(insertProperties, columns, "@")})", obj, tx);
}
}
public static async Task Update<T>(this DbConnection connection, T obj)
{
var type = typeof(T);
var tableName = TableMapper.GetTableName(type);
var allProperties = PropertiesCache.TypePropertiesCache(type);
var keyProperties = PropertiesCache.KeyPropertiesCache(type);
var computedProperties = PropertiesCache.ComputedPropertiesCache(type);
var columns = PropertiesCache.GetColumnNamesCache(type);
T obj1 = Activator.CreateInstance<T>();
var uProperties = allProperties.Except(computedProperties).Except(keyProperties).ToList();
var diffProperties = ComparePropertiesValue<T>(obj, obj1, uProperties);
await connection.QueryAsync($@"
UPDATE {FormatTableName(tableName)} Set {GetUpdateString(diffProperties, columns, " , ")}
WHERE {GetUpdateString(keyProperties, columns, " and ")}", obj);
}
private static List<PropertyInfo> ComparePropertiesValue<T>(T obj1, T obj2, IEnumerable<PropertyInfo> properties)
{
List<PropertyInfo> propertiesDiff = new List<PropertyInfo>();
foreach (PropertyInfo property in properties) {
if (property.GetValue(obj1, null) != property.GetValue(obj2, null))
{
propertiesDiff.Add(property);
}
}
return propertiesDiff;
}
private static string GetUpdateString(IEnumerable<PropertyInfo> properties, IReadOnlyDictionary<string, string> columnNames, string prefix)
{
return string.Join(prefix, properties.Select(p => $"{columnNames[p.Name]} = @{p.Name}"));
}
private static string GetColumnsString(IEnumerable<PropertyInfo> properties, IReadOnlyDictionary<string, string> columnNames, string tbName, string tablePrefix = "")
{
if (tbName != string.Empty) tbName = "tb" + tbName + "_";
if (tablePrefix == "target.")
{
return string.Join(", ", properties.Select(property => $"{tablePrefix}{columnNames[property.Name]} as {property.Name}"));
}
else if(tablePrefix == "@")
{
return string.Join(", ", properties.Select(property => $"{tablePrefix}{tbName + property.Name}"));
}
return string.Join(", ", properties.Select(property => $"{tablePrefix}{tbName + columnNames[property.Name].Replace("__", "")}"));
}
private static string GetColumnsString(IEnumerable<PropertyInfo> properties, IReadOnlyDictionary<string, string> columnNames, string tablePrefix = null)
{
return GetColumnsString(properties, columnNames, "", tablePrefix);
}
private static string FormatTableName(string table)
{
if (string.IsNullOrEmpty(table))
{
return table;
}
var parts = table.Split('.');
if (parts.Length == 1)
{
return $"{table}";
}
var tableName = "";
for (int i = 0; i < parts.Length; i++)
{
tableName += $"{parts[i]}";
if (i + 1 < parts.Length)
{
tableName += ".";
}
}
return tableName;
}
}
}