first commit
This commit is contained in:
173
ConsoleApp1/ORM/BulkQuery.cs
Normal file
173
ConsoleApp1/ORM/BulkQuery.cs
Normal file
@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ConsoleApp1.Model;
|
||||
|
||||
namespace ConsoleApp1.ORM
|
||||
{
|
||||
public class BulkQuery
|
||||
{
|
||||
public static void BulkInsert<TEntity>(IEnumerable<TEntity> entries)
|
||||
{
|
||||
var entityType = typeof(TEntity);
|
||||
var properties = entityType.GetProperties().Select(p => p.Name);
|
||||
BuildBulkInsertQuery(entityType.Name, properties, entries);
|
||||
}
|
||||
|
||||
private static void GetParametersValues(string tableName, IEnumerable<string> propertyNames, IEnumerable entries)
|
||||
{
|
||||
static object GetPropertyValue(object o, string propertyName)
|
||||
{
|
||||
//Debug.Assert(propertyName != null, nameof(propertyName) + " != null");
|
||||
var type = o.GetType();
|
||||
var property = type.GetProperty(propertyName);
|
||||
//Debug.Assert(property != null, nameof(property) + " != null");
|
||||
var propertyValue = property?.GetValue(o);
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
var fields = propertyNames as string[] ?? propertyNames.ToArray();
|
||||
var i = 0;
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
++i;
|
||||
Console.WriteLine($"Entry number {i}");
|
||||
foreach (var propertyName in fields)
|
||||
{
|
||||
var propertyValue = GetPropertyValue(entry, propertyName);
|
||||
Console.WriteLine($"Property name={propertyName}, value={propertyValue}");
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
private static void BuildBulkInsertQuery(string tableName,
|
||||
IEnumerable<string> propertyNames,
|
||||
IEnumerable entries,
|
||||
int maxBatchSize = 5)
|
||||
{
|
||||
using var session = NHibernateHelper.OpenSession();
|
||||
var cmd = session.Connection.CreateCommand();
|
||||
var columns = propertyNames as string[] ?? propertyNames.ToArray();
|
||||
var queryString = $"INSERT INTO {tableName} ({string.Join(',', columns)}) VALUES\n";
|
||||
var sb = new StringBuilder();
|
||||
|
||||
DbParameter CreateDbParameter(object value)
|
||||
{
|
||||
var pm = cmd.CreateParameter();
|
||||
pm.Value = value;
|
||||
return pm;
|
||||
}
|
||||
|
||||
static object GetPropertyValue(object o, string propertyName) => o.GetType().GetProperty(propertyName)?.GetValue(o);
|
||||
|
||||
var batchSize = 0;
|
||||
var p = 0;
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
// Build the names of the parameters
|
||||
var row = new StringBuilder("(");
|
||||
for (var ii = 0; ii < columns.Length; ii++)
|
||||
{
|
||||
row.Append($"@p{p + ii}");
|
||||
if (ii < columns.Length - 1) row.Append(",");
|
||||
|
||||
// Set parameter value
|
||||
var value = GetPropertyValue(entry, columns[ii]);
|
||||
cmd.Parameters.Add(CreateDbParameter(value));
|
||||
}
|
||||
p += columns.Length;
|
||||
row.Append(")");
|
||||
|
||||
// Add the row to our running SQL batch
|
||||
if (batchSize > 0) sb.AppendLine(",");
|
||||
sb.Append(row);
|
||||
batchSize += 1;
|
||||
|
||||
if (batchSize >= maxBatchSize)
|
||||
{
|
||||
var queryStringComplete = queryString + sb + ";";
|
||||
cmd.CommandText = queryStringComplete;
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Parameters.Clear();
|
||||
sb.Clear();
|
||||
batchSize = 0;
|
||||
p = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// handle the last few stragglers
|
||||
if (batchSize > 0)
|
||||
{
|
||||
var queryStringComplete = queryString + sb + ";";
|
||||
cmd.CommandText = queryStringComplete;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public static void BulkInsert1(IEnumerable<Person> persons)
|
||||
{
|
||||
using var session = NHibernateHelper.OpenSession();
|
||||
var cmd = session.Connection.CreateCommand();
|
||||
|
||||
var queryString = "INSERT INTO Person (Id, FirstName, LastName) VALUES\n";
|
||||
var sb = new StringBuilder();
|
||||
|
||||
var batchSize = 0;
|
||||
var p = 1; //the current paramter name (i.e. "@p1") we're going to use
|
||||
|
||||
DbParameter CreateDbParameter(object value)
|
||||
{
|
||||
var pm = cmd.CreateParameter();
|
||||
pm.Value = value;
|
||||
return pm;
|
||||
}
|
||||
|
||||
foreach (var person in persons)
|
||||
{
|
||||
//Build the names of the parameters
|
||||
var pId = $"@p{p}"; //the "Id" parameter name (i.e. "p1")
|
||||
var pFirstName = $"@p{p + 1}";
|
||||
var pLastName = $"@p{p + 2}";
|
||||
p += 3;
|
||||
|
||||
//Build a single "(p1, p2)" row
|
||||
var row = $"({pId}, {pFirstName}, {pLastName})"; //a single values tuple
|
||||
|
||||
//Add the row to our running SQL batch
|
||||
if (batchSize > 0) sb.AppendLine(",");
|
||||
sb.Append(row);
|
||||
batchSize += 1;
|
||||
|
||||
// Add the parameter values for this row
|
||||
cmd.Parameters.AddRange(new[] {
|
||||
CreateDbParameter(person.Id),
|
||||
CreateDbParameter(person.FirstName),
|
||||
CreateDbParameter(person.LastName)
|
||||
});
|
||||
|
||||
if (batchSize >= 5)
|
||||
{
|
||||
var queryStringComplete = queryString + sb;
|
||||
cmd.CommandText = queryStringComplete;
|
||||
cmd.ExecuteNonQuery();
|
||||
cmd.Parameters.Clear();
|
||||
sb.Clear();
|
||||
batchSize = 0;
|
||||
p = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//handle the last few stragglers
|
||||
if (batchSize > 0)
|
||||
{
|
||||
var queryStringComplete = queryString + sb;
|
||||
cmd.CommandText = queryStringComplete;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
ConsoleApp1/ORM/NHibernateHelper.cs
Normal file
48
ConsoleApp1/ORM/NHibernateHelper.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using System.Collections.Generic;
|
||||
using ConsoleApp1.Model;
|
||||
using NHibernate;
|
||||
using NHibernate.Cfg;
|
||||
using NHibernate.Cfg.MappingSchema;
|
||||
using NHibernate.Mapping.ByCode;
|
||||
|
||||
namespace ConsoleApp1.ORM
|
||||
{
|
||||
public static class NHibernateHelper
|
||||
{
|
||||
private static ISessionFactory _sessionFactory;
|
||||
private static Configuration _configuration;
|
||||
private static HbmMapping _mapping;
|
||||
|
||||
public static ISession OpenSession()
|
||||
{
|
||||
//Open and return the nhibernate session
|
||||
return SessionFactory.OpenSession();
|
||||
}
|
||||
|
||||
public static ISessionFactory SessionFactory => _sessionFactory ??= Configuration.BuildSessionFactory();
|
||||
|
||||
public static Configuration Configuration => _configuration ??= CreateConfiguration();
|
||||
|
||||
public static HbmMapping Mapping => _mapping ??= CreateMapping();
|
||||
|
||||
private static Configuration CreateConfiguration()
|
||||
{
|
||||
var configuration = new Configuration();
|
||||
//Loads properties from hibernate.cfg.xml
|
||||
configuration.Configure();
|
||||
//Loads nhibernate mappings
|
||||
configuration.AddDeserializedMapping(Mapping, null);
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
private static HbmMapping CreateMapping()
|
||||
{
|
||||
var mapper = new ModelMapper();
|
||||
//Add the person mapping to the model mapper
|
||||
mapper.AddMappings(new List<System.Type> { typeof(PersonMap) });
|
||||
//Create and return a HbmMapping of the model mapping in code
|
||||
return mapper.CompileMappingForAllExplicitlyAddedEntities();
|
||||
}
|
||||
}
|
||||
}
|
17
ConsoleApp1/ORM/SchemaTest.cs
Normal file
17
ConsoleApp1/ORM/SchemaTest.cs
Normal file
@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using NHibernate.Tool.hbm2ddl;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace ConsoleApp1.ORM
|
||||
{
|
||||
[TestFixture]
|
||||
public class SchemaTest
|
||||
{
|
||||
[Test]
|
||||
public void CanGenerateSchema()
|
||||
{
|
||||
var schemaUpdate = new SchemaUpdate(NHibernateHelper.Configuration);
|
||||
schemaUpdate.Execute(Console.WriteLine, true);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user