Added ability to return DynamicCachedReader from DB and convert it to DataTable
This commit is contained in:
@@ -96,6 +96,95 @@ namespace DynamORM
|
|||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
/// <summary>Create data reader from dynamic enumerable.</summary>
|
||||||
|
/// <param name="objects">List of objects.</param>
|
||||||
|
/// <returns>Instance of <see cref="DynamicCachedReader"/> containing objects data.</returns>
|
||||||
|
public static DynamicCachedReader FromDynamicEnumerable(IEnumerable<dynamic> objects)
|
||||||
|
{
|
||||||
|
var first = (objects as IEnumerable<dynamic>).FirstOrDefault();
|
||||||
|
|
||||||
|
if (first == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var firstDict = first as IDictionary<string, object>;
|
||||||
|
var r = new DynamicCachedReader();
|
||||||
|
r.Init(firstDict.Keys.Count);
|
||||||
|
|
||||||
|
for (int i = 0; i < firstDict.Keys.Count; i++)
|
||||||
|
r._types.Add(null);
|
||||||
|
|
||||||
|
foreach (dynamic elem in (objects as IEnumerable<dynamic>))
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
var dict = elem as IDictionary<string, object>;
|
||||||
|
|
||||||
|
foreach (var k in firstDict.Keys)
|
||||||
|
{
|
||||||
|
object val = dict[k];
|
||||||
|
|
||||||
|
r._cache.Add(val);
|
||||||
|
|
||||||
|
if (r._types[c] == null && val != null)
|
||||||
|
r._types[c] = val.GetType();
|
||||||
|
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
r._rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < firstDict.Keys.Count; i++)
|
||||||
|
if (r._types[i] == null)
|
||||||
|
r._types[i] = typeof(string);
|
||||||
|
|
||||||
|
r._schema = new DataTable("DYNAMIC");
|
||||||
|
r._schema.Columns.Add(new DataColumn("ColumnName", typeof(string)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("ColumnOrdinal", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("ColumnSize", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("NumericPrecision", typeof(short)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("NumericScale", typeof(short)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("DataType", typeof(Type)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("ProviderType", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("NativeType", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("AllowDBNull", typeof(bool)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("IsUnique", typeof(bool)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("IsKey", typeof(bool)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("IsAutoIncrement", typeof(bool)));
|
||||||
|
|
||||||
|
int ordinal = 0;
|
||||||
|
DataRow dr = null;
|
||||||
|
|
||||||
|
foreach (var column in firstDict.Keys)
|
||||||
|
{
|
||||||
|
dr = r._schema.NewRow();
|
||||||
|
|
||||||
|
dr[0] = column;
|
||||||
|
dr[1] = ordinal;
|
||||||
|
dr[2] = 0;
|
||||||
|
dr[3] = 0;
|
||||||
|
dr[4] = 0;
|
||||||
|
dr[5] = r._types[ordinal];
|
||||||
|
dr[6] = r._types[ordinal].ToDbType();
|
||||||
|
dr[7] = r._types[ordinal].ToDbType();
|
||||||
|
dr[8] = true;
|
||||||
|
dr[9] = false;
|
||||||
|
dr[10] = false;
|
||||||
|
dr[11] = false;
|
||||||
|
|
||||||
|
r._schema.Rows.Add(dr);
|
||||||
|
|
||||||
|
r._names.Add(dr[0].ToString());
|
||||||
|
r._ordinals.Add(dr[0].ToString().ToUpper(), ordinal++);
|
||||||
|
r._types.Add((Type)dr[5]);
|
||||||
|
|
||||||
|
dr.AcceptChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
dr.AcceptChanges();
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Create data reader from enumerable.</summary>
|
/// <summary>Create data reader from enumerable.</summary>
|
||||||
/// <typeparam name="T">Type of enumerated objects.</typeparam>
|
/// <typeparam name="T">Type of enumerated objects.</typeparam>
|
||||||
/// <param name="objects">List of objects.</param>
|
/// <param name="objects">List of objects.</param>
|
||||||
@@ -2773,6 +2862,44 @@ namespace DynamORM
|
|||||||
|
|
||||||
#endregion Query
|
#endregion Query
|
||||||
|
|
||||||
|
#region CachedQuery
|
||||||
|
|
||||||
|
/// <summary>Enumerate the reader and yield the result.</summary>
|
||||||
|
/// <param name="sql">SQL query containing numbered parameters in format provided by
|
||||||
|
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formatted with
|
||||||
|
/// <see cref="DynamicDatabase.DecorateName(string)"/> method.</param>
|
||||||
|
/// <param name="args">Arguments (parameters).</param>
|
||||||
|
/// <returns>Enumerator of objects expanded from query.</returns>
|
||||||
|
public virtual DynamicCachedReader CachedQuery(string sql, params object[] args)
|
||||||
|
{
|
||||||
|
using (IDbConnection con = Open())
|
||||||
|
using (IDbCommand cmd = con.CreateCommand())
|
||||||
|
{
|
||||||
|
using (IDataReader rdr = cmd
|
||||||
|
.SetCommand(sql)
|
||||||
|
.AddParameters(this, args)
|
||||||
|
.ExecuteReader())
|
||||||
|
return new DynamicCachedReader(rdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Enumerate the reader and yield the result.</summary>
|
||||||
|
/// <param name="builder">Command builder.</param>
|
||||||
|
/// <returns>Enumerator of objects expanded from query.</returns>
|
||||||
|
public virtual DynamicCachedReader CachedQuery(IDynamicQueryBuilder builder)
|
||||||
|
{
|
||||||
|
using (IDbConnection con = Open())
|
||||||
|
using (IDbCommand cmd = con.CreateCommand())
|
||||||
|
{
|
||||||
|
using (IDataReader rdr = cmd
|
||||||
|
.SetCommand(builder)
|
||||||
|
.ExecuteReader())
|
||||||
|
return new DynamicCachedReader(rdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Query
|
||||||
|
|
||||||
#region Schema
|
#region Schema
|
||||||
|
|
||||||
/// <summary>Builds query cache if necessary and returns it.</summary>
|
/// <summary>Builds query cache if necessary and returns it.</summary>
|
||||||
@@ -10855,6 +10982,45 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Extensions for data reader handling.</summary>
|
||||||
|
public static class DataReaderExtensions
|
||||||
|
{
|
||||||
|
/// <summary>Gets the data table from data reader.</summary>
|
||||||
|
/// <param name="r">The data reader.</param>
|
||||||
|
/// <param name="name">The name to give the table. If tableName is null or an empty string, a default name is given when added to the System.Data.DataTableCollection.</param>
|
||||||
|
/// <param name="nameSpace">The namespace for the XML representation of the data stored in the DataTable.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DataTable GetDataTableFromDataReader(this IDataReader r, string name = null, string nameSpace = null)
|
||||||
|
{
|
||||||
|
DataTable schemaTable = r.GetSchemaTable();
|
||||||
|
DataTable resultTable = new DataTable(name, nameSpace);
|
||||||
|
|
||||||
|
foreach (DataRow col in schemaTable.Rows)
|
||||||
|
{
|
||||||
|
dynamic c = col.RowToDynamicUpper();
|
||||||
|
|
||||||
|
DataColumn dataColumn = new DataColumn();
|
||||||
|
dataColumn.ColumnName = c.COLUMNNAME;
|
||||||
|
dataColumn.DataType = (Type)c.DATATYPE;
|
||||||
|
dataColumn.ReadOnly = true;
|
||||||
|
dataColumn.Unique = c.ISUNIQUE;
|
||||||
|
|
||||||
|
resultTable.Columns.Add(dataColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (r.Read())
|
||||||
|
{
|
||||||
|
DataRow row = resultTable.NewRow();
|
||||||
|
for (int i = 0; i < resultTable.Columns.Count - 1; i++)
|
||||||
|
row[i] = r[i];
|
||||||
|
|
||||||
|
resultTable.Rows.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultTable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Framework detection and specific implementations.</summary>
|
/// <summary>Framework detection and specific implementations.</summary>
|
||||||
public static class FrameworkTools
|
public static class FrameworkTools
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFrameworks>netstandard2.0;net472;net5.0;net6.0</TargetFrameworks>
|
<TargetFrameworks>netstandard2.0;net472;net5.0;net6.0</TargetFrameworks>
|
||||||
<Description>Dynamic Object-Relational Mapping library.</Description>
|
<Description>Dynamic Object-Relational Mapping library.</Description>
|
||||||
<Copyright>Copyright © RUSSEK Software 2012-2022</Copyright>
|
<Copyright>Copyright © RUSSEK Software 2012-2023</Copyright>
|
||||||
<Company>RUSSEK Software</Company>
|
<Company>RUSSEK Software</Company>
|
||||||
<Authors>Grzegorz Russek</Authors>
|
<Authors>Grzegorz Russek</Authors>
|
||||||
<VersionPrefix>1.2.4</VersionPrefix>
|
<VersionPrefix>1.2.5</VersionPrefix>
|
||||||
<RepositoryUrl>https://svn.dr4cul4.pl/svn/DynamORM/</RepositoryUrl>
|
<RepositoryUrl>https://svn.dr4cul4.pl/svn/DynamORM/</RepositoryUrl>
|
||||||
<PackageProjectUrl>https://dr4cul4.pl</PackageProjectUrl>
|
<PackageProjectUrl>https://dr4cul4.pl</PackageProjectUrl>
|
||||||
<Product>DynamORM</Product>
|
<Product>DynamORM</Product>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using DynamORM.Helpers;
|
using DynamORM.Helpers;
|
||||||
using DynamORM.Mapper;
|
using DynamORM.Mapper;
|
||||||
|
|
||||||
@@ -43,6 +44,95 @@ namespace DynamORM
|
|||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
/// <summary>Create data reader from dynamic enumerable.</summary>
|
||||||
|
/// <param name="objects">List of objects.</param>
|
||||||
|
/// <returns>Instance of <see cref="DynamicCachedReader"/> containing objects data.</returns>
|
||||||
|
public static DynamicCachedReader FromDynamicEnumerable(IEnumerable<dynamic> objects)
|
||||||
|
{
|
||||||
|
var first = (objects as IEnumerable<dynamic>).FirstOrDefault();
|
||||||
|
|
||||||
|
if (first == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var firstDict = first as IDictionary<string, object>;
|
||||||
|
var r = new DynamicCachedReader();
|
||||||
|
r.Init(firstDict.Keys.Count);
|
||||||
|
|
||||||
|
for (int i = 0; i < firstDict.Keys.Count; i++)
|
||||||
|
r._types.Add(null);
|
||||||
|
|
||||||
|
foreach (dynamic elem in (objects as IEnumerable<dynamic>))
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
var dict = elem as IDictionary<string, object>;
|
||||||
|
|
||||||
|
foreach (var k in firstDict.Keys)
|
||||||
|
{
|
||||||
|
object val = dict[k];
|
||||||
|
|
||||||
|
r._cache.Add(val);
|
||||||
|
|
||||||
|
if (r._types[c] == null && val != null)
|
||||||
|
r._types[c] = val.GetType();
|
||||||
|
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
r._rows++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < firstDict.Keys.Count; i++)
|
||||||
|
if (r._types[i] == null)
|
||||||
|
r._types[i] = typeof(string);
|
||||||
|
|
||||||
|
r._schema = new DataTable("DYNAMIC");
|
||||||
|
r._schema.Columns.Add(new DataColumn("ColumnName", typeof(string)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("ColumnOrdinal", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("ColumnSize", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("NumericPrecision", typeof(short)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("NumericScale", typeof(short)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("DataType", typeof(Type)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("ProviderType", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("NativeType", typeof(int)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("AllowDBNull", typeof(bool)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("IsUnique", typeof(bool)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("IsKey", typeof(bool)));
|
||||||
|
r._schema.Columns.Add(new DataColumn("IsAutoIncrement", typeof(bool)));
|
||||||
|
|
||||||
|
int ordinal = 0;
|
||||||
|
DataRow dr = null;
|
||||||
|
|
||||||
|
foreach (var column in firstDict.Keys)
|
||||||
|
{
|
||||||
|
dr = r._schema.NewRow();
|
||||||
|
|
||||||
|
dr[0] = column;
|
||||||
|
dr[1] = ordinal;
|
||||||
|
dr[2] = 0;
|
||||||
|
dr[3] = 0;
|
||||||
|
dr[4] = 0;
|
||||||
|
dr[5] = r._types[ordinal];
|
||||||
|
dr[6] = r._types[ordinal].ToDbType();
|
||||||
|
dr[7] = r._types[ordinal].ToDbType();
|
||||||
|
dr[8] = true;
|
||||||
|
dr[9] = false;
|
||||||
|
dr[10] = false;
|
||||||
|
dr[11] = false;
|
||||||
|
|
||||||
|
r._schema.Rows.Add(dr);
|
||||||
|
|
||||||
|
r._names.Add(dr[0].ToString());
|
||||||
|
r._ordinals.Add(dr[0].ToString().ToUpper(), ordinal++);
|
||||||
|
r._types.Add((Type)dr[5]);
|
||||||
|
|
||||||
|
dr.AcceptChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
dr.AcceptChanges();
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Create data reader from enumerable.</summary>
|
/// <summary>Create data reader from enumerable.</summary>
|
||||||
/// <typeparam name="T">Type of enumerated objects.</typeparam>
|
/// <typeparam name="T">Type of enumerated objects.</typeparam>
|
||||||
/// <param name="objects">List of objects.</param>
|
/// <param name="objects">List of objects.</param>
|
||||||
|
|||||||
@@ -1310,6 +1310,44 @@ namespace DynamORM
|
|||||||
|
|
||||||
#endregion Query
|
#endregion Query
|
||||||
|
|
||||||
|
#region CachedQuery
|
||||||
|
|
||||||
|
/// <summary>Enumerate the reader and yield the result.</summary>
|
||||||
|
/// <param name="sql">SQL query containing numbered parameters in format provided by
|
||||||
|
/// <see cref="DynamicDatabase.GetParameterName(object)"/> methods. Also names should be formatted with
|
||||||
|
/// <see cref="DynamicDatabase.DecorateName(string)"/> method.</param>
|
||||||
|
/// <param name="args">Arguments (parameters).</param>
|
||||||
|
/// <returns>Enumerator of objects expanded from query.</returns>
|
||||||
|
public virtual DynamicCachedReader CachedQuery(string sql, params object[] args)
|
||||||
|
{
|
||||||
|
using (IDbConnection con = Open())
|
||||||
|
using (IDbCommand cmd = con.CreateCommand())
|
||||||
|
{
|
||||||
|
using (IDataReader rdr = cmd
|
||||||
|
.SetCommand(sql)
|
||||||
|
.AddParameters(this, args)
|
||||||
|
.ExecuteReader())
|
||||||
|
return new DynamicCachedReader(rdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Enumerate the reader and yield the result.</summary>
|
||||||
|
/// <param name="builder">Command builder.</param>
|
||||||
|
/// <returns>Enumerator of objects expanded from query.</returns>
|
||||||
|
public virtual DynamicCachedReader CachedQuery(IDynamicQueryBuilder builder)
|
||||||
|
{
|
||||||
|
using (IDbConnection con = Open())
|
||||||
|
using (IDbCommand cmd = con.CreateCommand())
|
||||||
|
{
|
||||||
|
using (IDataReader rdr = cmd
|
||||||
|
.SetCommand(builder)
|
||||||
|
.ExecuteReader())
|
||||||
|
return new DynamicCachedReader(rdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Query
|
||||||
|
|
||||||
#region Schema
|
#region Schema
|
||||||
|
|
||||||
/// <summary>Builds query cache if necessary and returns it.</summary>
|
/// <summary>Builds query cache if necessary and returns it.</summary>
|
||||||
|
|||||||
44
DynamORM/Helpers/DataReaderExtensions.cs
Normal file
44
DynamORM/Helpers/DataReaderExtensions.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data;
|
||||||
|
|
||||||
|
namespace DynamORM.Helpers
|
||||||
|
{
|
||||||
|
/// <summary>Extensions for data reader handling.</summary>
|
||||||
|
public static class DataReaderExtensions
|
||||||
|
{
|
||||||
|
/// <summary>Gets the data table from data reader.</summary>
|
||||||
|
/// <param name="r">The data reader.</param>
|
||||||
|
/// <param name="name">The name to give the table. If tableName is null or an empty string, a default name is given when added to the System.Data.DataTableCollection.</param>
|
||||||
|
/// <param name="nameSpace">The namespace for the XML representation of the data stored in the DataTable.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static DataTable GetDataTableFromDataReader(this IDataReader r, string name = null, string nameSpace = null)
|
||||||
|
{
|
||||||
|
DataTable schemaTable = r.GetSchemaTable();
|
||||||
|
DataTable resultTable = new DataTable(name, nameSpace);
|
||||||
|
|
||||||
|
foreach (DataRow col in schemaTable.Rows)
|
||||||
|
{
|
||||||
|
dynamic c = col.RowToDynamicUpper();
|
||||||
|
|
||||||
|
DataColumn dataColumn = new DataColumn();
|
||||||
|
dataColumn.ColumnName = c.COLUMNNAME;
|
||||||
|
dataColumn.DataType = (Type)c.DATATYPE;
|
||||||
|
dataColumn.ReadOnly = true;
|
||||||
|
dataColumn.Unique = c.ISUNIQUE;
|
||||||
|
|
||||||
|
resultTable.Columns.Add(dataColumn);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (r.Read())
|
||||||
|
{
|
||||||
|
DataRow row = resultTable.NewRow();
|
||||||
|
for (int i = 0; i < resultTable.Columns.Count - 1; i++)
|
||||||
|
row[i] = r[i];
|
||||||
|
|
||||||
|
resultTable.Rows.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return resultTable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user