Created
February 12, 2025 07:52
-
-
Save sunmeat/02f8a56e1520ca0ce9a01ab3ad1ed129 to your computer and use it in GitHub Desktop.
JSON to SQL Server Dapper Plus Example
This file contains hidden or 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
// dotnet add package Newtonsoft.Json | |
using Microsoft.Data.SqlClient; | |
using Newtonsoft.Json; | |
using Z.Dapper.Plus; | |
using System.Reflection.Emit; | |
using System.Reflection; | |
namespace JSONToDatabase | |
{ | |
public class DynamicModelGenerator | |
{ | |
public static void Main(string[] args) | |
{ | |
string connectionString = "Server=localhost;Database=Store;Trusted_Connection=True;TrustServerCertificate=True;"; | |
string filePath = "C:/Users/Alex/Desktop/big.json"; | |
// чтение данных из JSON | |
var records = ReadJson(filePath); | |
// динамическое создание модели | |
var modelType = CreateDynamicModel(records); | |
// динамическое создание списка объектов этой модели | |
var dataList = MapDataToModel(records, modelType); | |
// подключение к базе данных и вставка данных | |
string tableName = "DynamicModel"; // название таблицы | |
CreateTableInDatabase(tableName, modelType, connectionString); // создание таблицы | |
using (var connection = new SqlConnection(connectionString)) | |
{ | |
connection.Open(); | |
connection.BulkInsert(dataList); // массовая вставка данных с использованием dapper plus | |
Console.WriteLine("Данные успешно вставлены в таблицу."); | |
} | |
} | |
// чтение данных из JSON | |
static List<Dictionary<string, string>> ReadJson(string filePath) | |
{ | |
var records = new List<Dictionary<string, string>>(); | |
var jsonData = File.ReadAllText(filePath); | |
var jsonArray = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(jsonData); | |
foreach (var record in jsonArray) | |
{ | |
var row = new Dictionary<string, string>(); | |
foreach (var kvp in record) | |
{ | |
row[kvp.Key] = kvp.Value.ToString(); | |
} | |
records.Add(row); | |
} | |
return records; | |
} | |
// динамическое создание модели на основе данных JSON | |
static Type CreateDynamicModel(List<Dictionary<string, string>> records) | |
{ | |
var columns = new List<string>(); | |
if (records.Count > 0) | |
{ | |
// берём первые записи для анализа колонок | |
var firstRecord = records[0]; | |
// получаем все ключи из первой записи | |
columns = firstRecord.Keys.ToList(); | |
} | |
if (columns.Count == 0) | |
{ | |
throw new Exception("JSON не содержит данных!"); | |
} | |
Console.WriteLine("Заголовки JSON: " + string.Join(", ", columns)); | |
// создаём динамическую модель | |
var assemblyName = new AssemblyName("DynamicModelAssembly"); | |
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); | |
var moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule"); | |
var typeBuilder = moduleBuilder.DefineType("DynamicModel", TypeAttributes.Public | TypeAttributes.Class); | |
// создаём свойства на основе колонок JSON | |
foreach (var column in columns) | |
{ | |
var fieldBuilder = typeBuilder.DefineField("_" + column, typeof(string), FieldAttributes.Private); | |
var propertyBuilder = typeBuilder.DefineProperty(column, PropertyAttributes.HasDefault, typeof(string), null); | |
var getterMethodBuilder = typeBuilder.DefineMethod("get_" + column, MethodAttributes.Public, typeof(string), Type.EmptyTypes); | |
var getterIl = getterMethodBuilder.GetILGenerator(); | |
getterIl.Emit(OpCodes.Ldarg_0); | |
getterIl.Emit(OpCodes.Ldfld, fieldBuilder); | |
getterIl.Emit(OpCodes.Ret); | |
var setterMethodBuilder = typeBuilder.DefineMethod("set_" + column, MethodAttributes.Public, null, new[] { typeof(string) }); | |
var setterIl = setterMethodBuilder.GetILGenerator(); | |
setterIl.Emit(OpCodes.Ldarg_0); | |
setterIl.Emit(OpCodes.Ldarg_1); | |
setterIl.Emit(OpCodes.Stfld, fieldBuilder); | |
setterIl.Emit(OpCodes.Ret); | |
propertyBuilder.SetGetMethod(getterMethodBuilder); | |
propertyBuilder.SetSetMethod(setterMethodBuilder); | |
} | |
return typeBuilder.CreateType(); | |
} | |
// преобразование данных в модель | |
static List<object> MapDataToModel(List<Dictionary<string, string>> records, Type modelType) | |
{ | |
var dataList = new List<object>(); | |
foreach (var row in records) | |
{ | |
if (row == null || row.Count == 0) continue; // проверка на пустые строки | |
var instance = Activator.CreateInstance(modelType); | |
foreach (var kvp in row) | |
{ | |
var property = modelType.GetProperty(kvp.Key); | |
if (property != null) | |
{ | |
property.SetValue(instance, kvp.Value); | |
} | |
} | |
dataList.Add(instance); | |
} | |
return dataList; | |
} | |
// создание таблицы в базе данных на основе динамической модели | |
static void CreateTableInDatabase(string tableName, Type modelType, string connectionString) | |
{ | |
using (var connection = new SqlConnection(connectionString)) | |
{ | |
connection.Open(); | |
var columns = modelType.GetProperties() | |
.Select(prop => $"[{prop.Name}] NVARCHAR(MAX)") // все колонки - строки (nvarchar(max)) | |
.ToList(); | |
string createTableQuery = $@" | |
IF OBJECT_ID('{tableName}', 'U') IS NULL | |
CREATE TABLE {tableName} ( | |
{string.Join(", ", columns)} | |
)"; | |
using (var command = new SqlCommand(createTableQuery, connection)) | |
{ | |
command.ExecuteNonQuery(); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment