Advertisement
yizraor

ru.stackoverflow.com/questions/785612

Feb 18th, 2018
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.95 KB | None | 0 0
  1. using System;
  2. using System.Linq;
  3. using System.Collections.ObjectModel;
  4. using System.Collections.Generic;
  5. using System.Reflection;
  6.  
  7. public interface IDbConnection { }
  8. public interface IDbTransaction { }
  9. public class CommandDefinition { }
  10. public class DapperRow { }
  11. public enum CommandType { }
  12.  
  13. public static class SqlMapper
  14. {
  15.     public static IEnumerable<dynamic> Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) => null;
  16.     public static IEnumerable<T> Query<T>(this IDbConnection cnn, CommandDefinition command) => null;
  17.  
  18.     public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
  19.     where T : new()
  20.     {
  21.         return (new T[] { new T() });
  22.     }
  23.  
  24.     public static IEnumerable<TReturn> Query<TFirst, TSecond, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  25.     public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  26.     public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  27.     public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  28.     public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  29.     public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn>(this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TFourth, TFifth, TSixth, TSeventh, TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  30.     public static IEnumerable<TReturn> Query<TReturn>(this IDbConnection cnn, string sql, Type[] types, Func<object[], TReturn> map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => null;
  31. }
  32.  
  33. class Solution
  34. {
  35.     public class baseTable { }
  36.     public class LOGS : baseTable { }
  37.     public class TRACK_EVENT : baseTable { }
  38.  
  39.     public static class MNLZContext
  40.     {
  41.         public class DbConnection : IDbConnection { }
  42.         public static IDbConnection oracleConnect = new DbConnection();
  43.     }
  44.  
  45.     public Dictionary<string, object> dbTables = new Dictionary<string, object>();
  46.  
  47.     public object getTableRows(string tableName, string sqlWhere = @"")
  48.     {
  49.         // взять тип таблицы, сидящей в dbTables[tableName]
  50.         Type tableType = dbTables[tableName].GetType();
  51.  
  52.         // проверить полученный тип
  53.         if (tableType.GetGenericTypeDefinition() != typeof(ObservableCollection<>))
  54.             throw new ArgumentException("Непонятный класс элемента dbTables[tableName]");
  55.  
  56.         // взять единственный generic-аргумент сконструированного класса ObservableCollection<T>
  57.         Type itemType = tableType.GetGenericArguments()[0];
  58.  
  59.         // получить обобщённый метод SqlMapper.Query<T>(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null)
  60.         MethodInfo generic_method = typeof(SqlMapper).GetMethods()
  61.             .Where(m => m.Name.Equals("Query"))
  62.             .Where(m => m.IsStatic)
  63.             .Where(m => m.GetParameters().Length == 7)
  64.             .Where(m => m.GetParameters()[0].ParameterType == typeof(IDbConnection))
  65.             .Where(m => m.GetParameters()[1].ParameterType == typeof(string))
  66.             .Where(m => m.GetParameters()[2].ParameterType == typeof(object))
  67.             .Where(m => m.GetParameters()[3].ParameterType == typeof(IDbTransaction))
  68.             .Where(m => m.GetParameters()[4].ParameterType == typeof(bool))
  69.             .Where(m => m.GetParameters()[5].ParameterType == typeof(int?))
  70.             .Where(m => m.GetParameters()[6].ParameterType == typeof(CommandType?))
  71.             .Where(m => m.ContainsGenericParameters)
  72.             .Single();
  73.         // создать сконструированный метод SqlMapper.Query<itemType>(IDbConnection, string, object, IDbTransaction, bool, int?, CommandType?)
  74.         MethodInfo constructed_method = generic_method.MakeGenericMethod(new Type[] { itemType });
  75.  
  76.         // строка запроса
  77.         string oracleSelectAllTableRows = @"SELECT * FROM " + tableName + ' ' + sqlWhere;
  78.         // формируем список параметров для вызова
  79.         object[] call_parameters = new object[]
  80.         {
  81.             MNLZContext.oracleConnect,
  82.             oracleSelectAllTableRows,
  83.             constructed_method.GetParameters()[2].DefaultValue,
  84.             constructed_method.GetParameters()[3].DefaultValue,
  85.             constructed_method.GetParameters()[4].DefaultValue,
  86.             constructed_method.GetParameters()[5].DefaultValue,
  87.             constructed_method.GetParameters()[6].DefaultValue
  88.         };
  89.         // делаем вызов сконструированного метода, чтобы получить новый набор данных 'tableRows'
  90.         // IEnumerable<itemType> tableRows = MNLZContext.oracleConnect.Query<itemType>(oracleSelectAllTableRows);
  91.         // IEnumerable<itemType> tableRows = SqlMapper.Query<itemType>(MNLZContext.oracleConnect, oracleSelectAllTableRows[, null, null, true, null, null]);
  92.         // поскольку вызывается статический метод, то первый параметр .Invoke() ставим 'null' (объекта нет)
  93.         object tableRows = constructed_method.Invoke(null, call_parameters);
  94.  
  95.         // конструируем тип IEnumerable<itemType>
  96.         Type ienumerableType = typeof(IEnumerable<>).MakeGenericType(new Type[] { itemType });
  97.         // запрашиваем у типа таблицы ObservableCollection<itemType> подходящий конструктор
  98.         ConstructorInfo constructor = tableType.GetConstructors()
  99.             .Where(c => c.GetParameters().Length == 1)
  100.             .Where(c => c.GetParameters()[0].ParameterType.IsEquivalentTo(ienumerableType))
  101.             .Single();
  102.  
  103.         // конструируем и возвращаем коллекцию 'ObservableCollection<itemType>(tableRows)'
  104.         return constructor.Invoke(new object[] { tableRows });
  105.     }
  106.  
  107.     public void Prepare()
  108.     {
  109.         dbTables["test1"] = new ObservableCollection<LOGS>(Enumerable.Repeat(new LOGS(), 3));
  110.         dbTables["test2"] = new ObservableCollection<TRACK_EVENT>(Enumerable.Repeat(new TRACK_EVENT(), 4));
  111.     }
  112.  
  113.     public void PrintInfo(string tableName, string addition)
  114.     {
  115.         Console.WriteLine($"  {addition}: dbTables[\"{tableName}\"]'s type is '{dbTables[tableName].GetType().Name}<{dbTables[tableName].GetType().GetGenericArguments()[0].Name}>'");
  116.  
  117.         if (dbTables[tableName] is ObservableCollection<LOGS> t_1)
  118.         {
  119.             Console.WriteLine($"  {addition}: dbTables[\"{tableName}\"].Count = {t_1.Count}");
  120.             Console.WriteLine($"  {addition}: dbTables[\"{tableName}\"]'s item[0] type is '{t_1[0].GetType().Name}'");
  121.         }
  122.         else if (dbTables[tableName] is ObservableCollection<TRACK_EVENT> t_2)
  123.         {
  124.             Console.WriteLine($"  {addition}: dbTables[\"{tableName}\"].Count = {t_2.Count}");
  125.             Console.WriteLine($"  {addition}: dbTables[\"{tableName}\"]'s item[0] type is '{t_2[0].GetType().Name}'");
  126.         }
  127.         else
  128.             throw new Exception("Что-то поломалось в типах элементов 'dbTables[]'");
  129.     }
  130.  
  131.     public void Test()
  132.     {
  133.         foreach (string tableName in dbTables.Keys.ToList())
  134.         {
  135.             Console.WriteLine($"key: '{tableName}'");
  136.             PrintInfo(tableName, "old");
  137.             dbTables[tableName] = getTableRows(tableName);
  138.             PrintInfo(tableName, "new");
  139.         }
  140.  
  141.         Console.WriteLine("==========");
  142.     }
  143.  
  144.     static void Main(string[] args)
  145.     {
  146.         Solution test_object = new Solution();
  147.         test_object.Prepare();
  148.         test_object.Test();
  149.         test_object.Test();
  150.     }
  151. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement