Created
March 11, 2022 00:50
-
-
Save roobie/da3b91430d18c7e2a40cc2b9480f31a4 to your computer and use it in GitHub Desktop.
make a dto via reflection
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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