Skip to content

Instantly share code, notes, and snippets.

@roobie
Created March 11, 2022 00:50
Show Gist options
  • Save roobie/da3b91430d18c7e2a40cc2b9480f31a4 to your computer and use it in GitHub Desktop.
Save roobie/da3b91430d18c7e2a40cc2b9480f31a4 to your computer and use it in GitHub Desktop.
make a dto via reflection
using System.Data;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
namespace Shovel.Lib;
public static class DataTableExtensions
{
public static IEnumerable<T> IntoDtos<T>(this DataRowCollection rows)
where T : class, new()
{
foreach(DataRow row in rows)
{
yield return row.IntoDto<T>();
}
}
public static T IntoDto<T>(this DataRow dataRow)
where T : class, new()
{
T targetObject = new();
Type typeofTarget = typeof(T);
PropertyInfo[] allProperties = typeofTarget
.GetProperties(BindingFlags.Public | BindingFlags.Instance);
var setters = allProperties.Where(property => property.CanWrite);
var methodParametersContainer = new object[1];
foreach (PropertyInfo setter in setters)
{
var columnAttr = setter.GetCustomAttribute<System.ComponentModel.DataAnnotations.Schema.ColumnAttribute>(false);
Console.WriteLine(columnAttr);
//Remove "set_" from method name
string columnName = setter
.Name
.ToLower();
// If row contains value for method...
if (dataRow.Table.Columns.Contains(columnName))
{
// If the value from the database is null, do not assign.
if (dataRow[columnName] == DBNull.Value)
{
continue;
}
// Fill the container with the data to assign
methodParametersContainer[0] = dataRow[columnName];
// Invoke the setter method
setter.GetSetMethod().Invoke(targetObject, methodParametersContainer);
}
}
return targetObject;
}
}
using System;
using System.Data;
using System.ComponentModel.DataAnnotations.Schema;
using System.IO;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Shovel.Lib;
using Microsoft.Data.Sqlite;
var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(builder =>
{
builder.AddConsole();
})
.ConfigureServices(services =>
{
services.AddTransient<InitializationOperation>();
services.AddTransient<ShovelProcessor>();
})
.Build();
var init = host.Services.GetRequiredService<InitializationOperation>();
await init.ExecuteAsync();
class InitializationOperation
{
ShovelProcessor processor;
public InitializationOperation(ILogger<InitializationOperation> logger,
ShovelProcessor processor)
{
var assemblyName = Assembly.GetExecutingAssembly().GetName();
var name = assemblyName.Name;
var version = assemblyName.Version;
logger.LogInformation("{0} version {1}", name, version);
this.processor = processor;
}
public async Task ExecuteAsync(CancellationToken stoppingToken = default)
{
await this.processor.ExecuteAsync(stoppingToken);
}
}
class ShovelProcessor
{
private readonly ILogger<ShovelProcessor> logger;
public ShovelProcessor(ILogger<ShovelProcessor> logger)
{
this.logger = logger;
}
public async Task ExecuteAsync(CancellationToken stoppingToken = default)
{
this.logger.LogInformation("Doing something");
await Task.Delay(TimeSpan.FromSeconds(1));
var connStringBuilder = new SqliteConnectionStringBuilder
{
DataSource = ":memory:"
};
using SqliteConnection conn = new(connStringBuilder.ToString());
await conn.OpenAsync();
var cmd = conn.CreateCommand();
cmd.CommandText = await File.ReadAllTextAsync("test.sql");
await cmd.ExecuteNonQueryAsync();
cmd.CommandText = @"SELECT * FROM test_record;";
using var reader = await cmd.ExecuteReaderAsync();
using DataTable table = new();
table.Load(reader);
var tableAsJson = Newtonsoft.Json.JsonConvert.SerializeObject(table);
Console.WriteLine(tableAsJson);
var row = table.Rows[0];
var obj = row.IntoDto<TestRecord>();
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(obj));
var listOfObj = Newtonsoft.Json.JsonConvert.DeserializeObject<TestRecord[]>(tableAsJson);
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(listOfObj));
var listOfObj2 = table.Rows.IntoDtos<TestRecord>();
Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(listOfObj2));
}
}
// record TestRecord(int id, string label, string moniker);
class TestRecord
{
[Column("id")]
public long? Id { get; set; }
[Column("label")]
public string? Label { get; set; }
[Column("moniker")]
public string? Moniker { get; set; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment