using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; namespace ConsoleApp2 { class Program { static void Main(string[] args) { var repository = new SellerStatsRepository(); foreach (var seller in repository.GetSellers()) { Console.WriteLine($"Seller {seller.Name} is {seller.Age} years old."); } foreach (var seller in repository.GetSellersHavingInvoiceCountOf(42)) { Console.WriteLine($"Seller {seller.Name} is {seller.Age} years old."); } Console.ReadKey(true); } } public class SellerModel { public string Name { get; set; } public int Age { get; set; } } public class SellerStatsRepository: RepositoryBase { public IList GetSellersHavingInvoiceCountOf(int invoiceCount) { var param = new { invoiceCount }; return ExecuteView(record => new SellerModel { Name = (string)record["Name"], Age = (int)record["Age"] }, param).ToList().AsReadOnly(); } public IList GetSellers() { return ExecuteView(record => new SellerModel { Name = (string) record["Name"], Age = (int) record["Age"] }).ToList().AsReadOnly(); } } public abstract class RepositoryBase { public static IDictionary ToDictionary(object o) => o?.GetType()?.GetProperties()?.ToDictionary(member => member.Name, member => member.GetValue(o)) ?? new Dictionary(); [MethodImpl(MethodImplOptions.NoInlining)] //object is type of record set and builder contains logic of mapping //TODO: change Dictionary type to ORM record type public IEnumerable ExecuteView(Func, T> builder, object args = null) { var parameters = ToDictionary(args); var stackTrace = new StackTrace(); var frame = stackTrace.GetFrame(1); var method = frame.GetMethod(); var assembly = method.DeclaringType.Assembly; using (var stream = assembly.GetManifestResourceStream($"{method.DeclaringType.Namespace}.{method.Name}.sql")) { using (var reader = new StreamReader(stream)) { var sql = reader.ReadToEnd(); Console.WriteLine("Executing SQL {0}", sql); Console.WriteLine("With params:"); foreach (var parameter in parameters) { Console.WriteLine($"- {parameter.Key}: {parameter.Value}"); } // TODO: execute SQL passing parameters var records = new List> { new Dictionary { { "Name", "nom 1" }, { "Age", 32 } }, new Dictionary { { "Name", "nom 2" }, { "Age", 35 } } }; return records.Select(builder); } } } } }