Memory Leaks
This commit is contained in:
@@ -1901,8 +1901,12 @@ namespace DynamORM
|
||||
Dictionary<string, DynamicSchemaColumn> schema = null;
|
||||
|
||||
if (mapper != null)
|
||||
{
|
||||
tableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
|
||||
mapper.Type.Name : mapper.Table.Name;
|
||||
owner = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Owner) ?
|
||||
null : mapper.Table.Owner;
|
||||
}
|
||||
|
||||
bool databaseSchemaSupport = !string.IsNullOrEmpty(tableName) &&
|
||||
(Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
||||
@@ -4052,7 +4056,7 @@ namespace DynamORM
|
||||
Dictionary<string, DynamicSchemaColumn> schema = null;
|
||||
|
||||
schema = Database.GetSchema(TableType) ??
|
||||
Database.GetSchema(TableName);
|
||||
Database.GetSchema(TableName, OwnerName);
|
||||
|
||||
#region Fill currrent table schema
|
||||
|
||||
@@ -4437,7 +4441,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicInsertQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.Table(this.TableName, this.Schema);
|
||||
builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName), this.Schema);
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
@@ -4484,7 +4488,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicUpdateQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.Table(this.TableName, this.Schema);
|
||||
builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName), this.Schema);
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
@@ -4539,7 +4543,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicDeleteQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.Table(this.TableName, this.Schema);
|
||||
builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName), this.Schema);
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
@@ -4591,7 +4595,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicSelectQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.From(x => this.TableName);
|
||||
builder.From(x => string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName));
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
|
||||
@@ -29,12 +29,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using DynamORM.Helpers;
|
||||
|
||||
namespace DynamORM.Builders
|
||||
{
|
||||
/// <summary>Dynamic query builder base interface.</summary>
|
||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||
public interface IDynamicQueryBuilder
|
||||
public interface IDynamicQueryBuilder : IExtendedDisposable
|
||||
{
|
||||
/// <summary>Gets <see cref="DynamicDatabase"/> instance.</summary>
|
||||
DynamicDatabase Database { get; }
|
||||
|
||||
@@ -26,10 +26,12 @@
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using DynamORM.Helpers;
|
||||
|
||||
namespace DynamORM.Builders
|
||||
{
|
||||
/// <summary>Interface describing parameter info.</summary>
|
||||
public interface IParameter
|
||||
public interface IParameter : IExtendedDisposable
|
||||
{
|
||||
/// <summary>Gets the parameter position in command.</summary>
|
||||
/// <remarks>Available after filling the command.</remarks>
|
||||
|
||||
@@ -27,11 +27,12 @@
|
||||
*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
using DynamORM.Helpers;
|
||||
|
||||
namespace DynamORM.Builders
|
||||
{
|
||||
/// <summary>Interface describing table information.</summary>
|
||||
public interface ITableInfo
|
||||
public interface ITableInfo : IExtendedDisposable
|
||||
{
|
||||
/// <summary>Gets table owner name.</summary>
|
||||
string Owner { get; }
|
||||
|
||||
@@ -206,5 +206,18 @@ namespace DynamORM.Builders.Implementation
|
||||
}
|
||||
|
||||
#endregion Insert
|
||||
|
||||
#region IExtendedDisposable
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
_columns = _values = null;
|
||||
}
|
||||
|
||||
#endregion IExtendedDisposable
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,7 @@ namespace DynamORM.Builders.Implementation
|
||||
/// </summary>
|
||||
internal TableInfo()
|
||||
{
|
||||
IsDisposed = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -76,6 +77,7 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <param name="alias">The table alias.</param>
|
||||
/// <param name="owner">The table owner.</param>
|
||||
public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Alias = alias;
|
||||
@@ -93,6 +95,7 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <param name="alias">The table alias.</param>
|
||||
/// <param name="owner">The table owner.</param>
|
||||
public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null)
|
||||
: this()
|
||||
{
|
||||
var mapper = DynamicMapperCache.GetMapper(type);
|
||||
|
||||
@@ -116,6 +119,20 @@ namespace DynamORM.Builders.Implementation
|
||||
|
||||
/// <summary>Gets or sets table schema.</summary>
|
||||
public Dictionary<string, DynamicSchemaColumn> Schema { get; internal set; }
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
Schema.Clear();
|
||||
Owner = Name = Alias = null;
|
||||
Schema = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Generic based table information.</summary>
|
||||
@@ -141,6 +158,13 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <summary>Interface describing parameter info.</summary>
|
||||
internal class Parameter : IParameter
|
||||
{
|
||||
/// <summary>Initializes a new instance of the
|
||||
/// <see cref="Parameter"/> class.</summary>
|
||||
public Parameter()
|
||||
{
|
||||
IsDisposed = false;
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets the parameter position in command.</summary>
|
||||
/// <remarks>Available after filling the command.</remarks>
|
||||
public int Ordinal { get; internal set; }
|
||||
@@ -159,6 +183,19 @@ namespace DynamORM.Builders.Implementation
|
||||
|
||||
/// <summary>Gets or sets the parameter schema information.</summary>
|
||||
public DynamicSchemaColumn? Schema { get; set; }
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
Name = null;
|
||||
Schema = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Parameter
|
||||
@@ -171,6 +208,7 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <param name="db">The database.</param>
|
||||
public DynamicQueryBuilder(DynamicDatabase db)
|
||||
{
|
||||
IsDisposed = false;
|
||||
VirtualMode = false;
|
||||
Tables = new List<ITableInfo>();
|
||||
Parameters = new Dictionary<string, IParameter>();
|
||||
@@ -179,6 +217,9 @@ namespace DynamORM.Builders.Implementation
|
||||
OpenBracketsCount = 0;
|
||||
|
||||
Database = db;
|
||||
if (Database != null)
|
||||
Database.AddToCache(this);
|
||||
|
||||
SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
||||
}
|
||||
|
||||
@@ -330,7 +371,9 @@ namespace DynamORM.Builders.Implementation
|
||||
// If node is a delegate, parse it to create the logical tree...
|
||||
if (node is Delegate)
|
||||
{
|
||||
node = DynamicParser.Parse((Delegate)node).Result;
|
||||
using (var p = DynamicParser.Parse((Delegate)node))
|
||||
node = p.Result;
|
||||
|
||||
return Parse(node, ref columnSchema, pars, rawstr, decorate: decorate); // Intercept containers as in (x => "string")
|
||||
}
|
||||
|
||||
@@ -813,5 +856,43 @@ namespace DynamORM.Builders.Implementation
|
||||
}
|
||||
|
||||
#endregion Helpers
|
||||
|
||||
#region IExtendedDisposable
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
if (Database != null)
|
||||
Database.RemoveFromCache(this);
|
||||
|
||||
if (Parameters != null)
|
||||
{
|
||||
foreach (var p in Parameters)
|
||||
p.Value.Dispose();
|
||||
|
||||
Parameters.Clear();
|
||||
Parameters = null;
|
||||
}
|
||||
|
||||
if (Tables != null)
|
||||
{
|
||||
foreach (var t in Tables)
|
||||
t.Dispose();
|
||||
|
||||
Tables.Clear();
|
||||
Tables = null;
|
||||
}
|
||||
|
||||
WhereCondition = null;
|
||||
Database = null;
|
||||
}
|
||||
|
||||
#endregion IExtendedDisposable
|
||||
}
|
||||
}
|
||||
@@ -1298,5 +1298,18 @@ namespace DynamORM.Builders.Implementation
|
||||
}
|
||||
|
||||
#endregion Helpers
|
||||
|
||||
#region IExtendedDisposable
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
_select = _from = _join = _groupby = _orderby = null;
|
||||
}
|
||||
|
||||
#endregion IExtendedDisposable
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,11 @@ namespace DynamORM.Builders.Implementation
|
||||
index++;
|
||||
if (f == null)
|
||||
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
|
||||
var result = DynamicParser.Parse(f).Result;
|
||||
|
||||
object result = null;
|
||||
|
||||
using (var p = DynamicParser.Parse(f))
|
||||
result = p.Result;
|
||||
|
||||
if (result == null)
|
||||
throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
|
||||
@@ -318,5 +322,18 @@ namespace DynamORM.Builders.Implementation
|
||||
}
|
||||
|
||||
#endregion Where
|
||||
|
||||
#region IExtendedDisposable
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
_columns = null;
|
||||
}
|
||||
|
||||
#endregion IExtendedDisposable
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,10 @@ namespace DynamORM
|
||||
|
||||
IsDisposed = true;
|
||||
|
||||
_command.Parameters.Clear();
|
||||
|
||||
_command.Dispose();
|
||||
_command = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +94,9 @@ namespace DynamORM
|
||||
/// <summary>Gets schema columns cache.</summary>
|
||||
internal Dictionary<string, Dictionary<string, DynamicSchemaColumn>> Schema { get; private set; }
|
||||
|
||||
/// <summary>Gets active builders that weren't disposed.</summary>
|
||||
internal List<IDynamicQueryBuilder> RemainingBuilders { get; private set; }
|
||||
|
||||
#if !DYNAMORM_OMMIT_OLDSYNTAX
|
||||
|
||||
/// <summary>Gets tables cache for this database instance.</summary>
|
||||
@@ -164,6 +167,7 @@ namespace DynamORM
|
||||
TransactionPool = new Dictionary<IDbConnection, Stack<IDbTransaction>>();
|
||||
CommandsPool = new Dictionary<IDbConnection, List<IDbCommand>>();
|
||||
Schema = new Dictionary<string, Dictionary<string, DynamicSchemaColumn>>();
|
||||
RemainingBuilders = new List<IDynamicQueryBuilder>();
|
||||
#if !DYNAMORM_OMMIT_OLDSYNTAX
|
||||
TablesCache = new Dictionary<string, DynamicTable>();
|
||||
#endif
|
||||
@@ -248,6 +252,22 @@ namespace DynamORM
|
||||
|
||||
#endregion Table
|
||||
|
||||
/// <summary>Adds cached builder.</summary>
|
||||
/// <param name="builder">New dynamic builder.</param>
|
||||
internal void AddToCache(IDynamicQueryBuilder builder)
|
||||
{
|
||||
lock (SyncLock)
|
||||
RemainingBuilders.Add(builder);
|
||||
}
|
||||
|
||||
/// <summary>Removes cached builder.</summary>
|
||||
/// <param name="builder">Disposed dynamic builder.</param>
|
||||
internal void RemoveFromCache(IDynamicQueryBuilder builder)
|
||||
{
|
||||
lock (SyncLock)
|
||||
RemainingBuilders.Remove(builder);
|
||||
}
|
||||
|
||||
#region From/Insert/Update/Delete
|
||||
|
||||
/// <summary>
|
||||
@@ -960,7 +980,11 @@ namespace DynamORM
|
||||
{
|
||||
lock (SyncLock)
|
||||
if (Schema.ContainsKey(table.FullName))
|
||||
{
|
||||
if (Schema[table.FullName] != null)
|
||||
Schema[table.FullName].Clear();
|
||||
Schema.Remove(table.FullName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Clears the all schemas from cache.</summary>
|
||||
@@ -968,7 +992,13 @@ namespace DynamORM
|
||||
public void ClearSchema()
|
||||
{
|
||||
lock (SyncLock)
|
||||
{
|
||||
foreach (var s in Schema)
|
||||
if (s.Value != null)
|
||||
s.Value.Clear();
|
||||
|
||||
Schema.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get schema describing objects from reader.</summary>
|
||||
@@ -1015,8 +1045,12 @@ namespace DynamORM
|
||||
Dictionary<string, DynamicSchemaColumn> schema = null;
|
||||
|
||||
if (mapper != null)
|
||||
{
|
||||
tableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
|
||||
mapper.Type.Name : mapper.Table.Name;
|
||||
owner = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Owner) ?
|
||||
null : mapper.Table.Owner;
|
||||
}
|
||||
|
||||
bool databaseSchemaSupport = !string.IsNullOrEmpty(tableName) &&
|
||||
(Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
|
||||
@@ -1285,6 +1319,7 @@ namespace DynamORM
|
||||
|
||||
// Dispose the corpse
|
||||
connection.Dispose();
|
||||
connection = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1378,6 +1413,8 @@ namespace DynamORM
|
||||
TablesCache.Clear();
|
||||
|
||||
tables.ForEach(t => t.Dispose());
|
||||
tables.Clear();
|
||||
tables = null;
|
||||
#endif
|
||||
|
||||
foreach (var con in TransactionPool)
|
||||
@@ -1389,6 +1426,8 @@ namespace DynamORM
|
||||
tmp.ForEach(cmd => cmd.Dispose());
|
||||
|
||||
CommandsPool[con.Key].Clear();
|
||||
tmp.Clear();
|
||||
CommandsPool[con.Key] = tmp = null;
|
||||
}
|
||||
|
||||
// Rollback remaining transactions
|
||||
@@ -1407,13 +1446,23 @@ namespace DynamORM
|
||||
con.Key.Dispose();
|
||||
}
|
||||
|
||||
while (RemainingBuilders.Count > 0)
|
||||
RemainingBuilders.First().Dispose();
|
||||
|
||||
// Clear pools
|
||||
lock (SyncLock)
|
||||
{
|
||||
TransactionPool.Clear();
|
||||
CommandsPool.Clear();
|
||||
RemainingBuilders.Clear();
|
||||
|
||||
TransactionPool = null;
|
||||
CommandsPool = null;
|
||||
RemainingBuilders = null;
|
||||
}
|
||||
|
||||
ClearSchema();
|
||||
|
||||
IsDisposed = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ namespace DynamORM
|
||||
Dictionary<string, DynamicSchemaColumn> schema = null;
|
||||
|
||||
schema = Database.GetSchema(TableType) ??
|
||||
Database.GetSchema(TableName);
|
||||
Database.GetSchema(TableName, OwnerName);
|
||||
|
||||
#region Fill currrent table schema
|
||||
|
||||
@@ -674,7 +674,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicInsertQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.Table(this.TableName, this.Schema);
|
||||
builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName), this.Schema);
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
@@ -721,7 +721,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicUpdateQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.Table(this.TableName, this.Schema);
|
||||
builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName), this.Schema);
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
@@ -776,7 +776,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicDeleteQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.Table(this.TableName, this.Schema);
|
||||
builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName), this.Schema);
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
@@ -828,7 +828,7 @@ namespace DynamORM
|
||||
HandleTypeArgument<DynamicSelectQueryBuilder>(null, info, ref types, builder, 0);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
|
||||
builder.From(x => this.TableName);
|
||||
builder.From(x => string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, this.TableName));
|
||||
|
||||
// loop the named args - see if we have order, columns and constraints
|
||||
if (info.ArgumentNames.Count > 0)
|
||||
|
||||
@@ -54,6 +54,8 @@ namespace DynamORM.Helpers.Dynamics
|
||||
[Serializable]
|
||||
public class Node : IDynamicMetaObjectProvider, IExtendedDisposable, ISerializable
|
||||
{
|
||||
private DynamicParser _parser = null;
|
||||
|
||||
#region MetaNode
|
||||
|
||||
/// <summary>
|
||||
@@ -763,6 +765,23 @@ namespace DynamORM.Helpers.Dynamics
|
||||
|
||||
return string.Format("({0} {1} {2})", Host.Sketch(), Operation, Right.Sketch());
|
||||
}
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
|
||||
if (Right != null && Right is Node)
|
||||
{
|
||||
Node n = (Node)Right;
|
||||
|
||||
if (!n.IsDisposed)
|
||||
n.Dispose();
|
||||
|
||||
Right = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Binary
|
||||
@@ -889,7 +908,16 @@ namespace DynamORM.Helpers.Dynamics
|
||||
public Node Host { get; internal set; }
|
||||
|
||||
/// <summary>Gets reference to the parser.</summary>
|
||||
public DynamicParser Parser { get; internal set; }
|
||||
public DynamicParser Parser
|
||||
{
|
||||
get { return _parser; }
|
||||
internal set
|
||||
{
|
||||
_parser = value;
|
||||
if (_parser != null)
|
||||
_parser._allNodes.Add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Node"/> class.
|
||||
@@ -982,12 +1010,18 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
if (Host != null && !Host.IsDisposed)
|
||||
Host.Dispose();
|
||||
|
||||
Host = null;
|
||||
|
||||
Parser = null;
|
||||
}
|
||||
|
||||
#endregion Implementation of IExtendedDisposable
|
||||
@@ -1017,6 +1051,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
#region Data
|
||||
|
||||
private List<Node.Argument> _arguments = new List<Node.Argument>();
|
||||
private List<Node> _allNodes = new List<Node>();
|
||||
private object _uncertainResult;
|
||||
|
||||
#endregion Data
|
||||
@@ -1129,6 +1164,34 @@ namespace DynamORM.Helpers.Dynamics
|
||||
public void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
if (_uncertainResult != null && _uncertainResult is Node)
|
||||
{
|
||||
((Node)_uncertainResult).Dispose();
|
||||
_uncertainResult = null;
|
||||
}
|
||||
|
||||
if (Last != null && !Last.IsDisposed)
|
||||
{
|
||||
Last.Dispose();
|
||||
Last = null;
|
||||
}
|
||||
|
||||
if (_arguments != null)
|
||||
{
|
||||
_arguments.ForEach(x => { if (!x.IsDisposed) x.Dispose(); });
|
||||
|
||||
_arguments.Clear();
|
||||
_arguments = null;
|
||||
}
|
||||
|
||||
if (_allNodes != null)
|
||||
{
|
||||
_allNodes.ForEach(x => { if (!x.IsDisposed) x.Dispose(); });
|
||||
|
||||
_allNodes.Clear();
|
||||
_allNodes = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implementation of IExtendedDisposable
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// <summary>Class that allows to use interfaces as dynamic objects.</summary>
|
||||
/// <typeparam name="T">Type of class to proxy.</typeparam>
|
||||
/// <remarks>This is temporary solution. Which allows to use builders as a dynamic type.</remarks>
|
||||
public class DynamicProxy<T> : DynamicObject
|
||||
public class DynamicProxy<T> : DynamicObject, IDisposable
|
||||
{
|
||||
private T _proxy;
|
||||
private Type _type;
|
||||
@@ -59,15 +59,15 @@ namespace DynamORM.Helpers.Dynamics
|
||||
_proxy = proxiedObject;
|
||||
_type = typeof(T);
|
||||
|
||||
var members = GetAllMembers(_type);
|
||||
var mapper = Mapper.DynamicMapperCache.GetMapper<T>();
|
||||
|
||||
_properties = members
|
||||
.Where(x => x is PropertyInfo)
|
||||
_properties = mapper
|
||||
.ColumnsMap
|
||||
.ToDictionary(
|
||||
k => k.Name,
|
||||
v => new DynamicPropertyInvoker((PropertyInfo)v, null));
|
||||
k => k.Value.Name,
|
||||
v => v.Value);
|
||||
|
||||
_methods = members
|
||||
_methods = GetAllMembers(_type)
|
||||
.Where(x => x is MethodInfo)
|
||||
.Cast<MethodInfo>()
|
||||
.Where(m => !((m.Name.StartsWith("set_") && m.ReturnType == typeof(void)) || m.Name.StartsWith("get_")))
|
||||
@@ -312,5 +312,21 @@ namespace DynamORM.Helpers.Dynamics
|
||||
|
||||
return type.GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
|
||||
}
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
object res;
|
||||
TryInvokeMethod("Dispose", out res, new object[] { });
|
||||
|
||||
_methods.Clear();
|
||||
_properties.Clear();
|
||||
|
||||
_methods = null;
|
||||
_properties = null;
|
||||
_type = null;
|
||||
_proxy = default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,9 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace DynamORM.Mapper
|
||||
{
|
||||
@@ -76,7 +78,7 @@ namespace DynamORM.Mapper
|
||||
var propertyMap = new Dictionary<string, string>();
|
||||
var ignored = new List<string>();
|
||||
|
||||
foreach (var pi in Type.GetProperties())
|
||||
foreach (var pi in GetAllMembers(Type).Where(x => x is PropertyInfo).Cast<PropertyInfo>())
|
||||
{
|
||||
ColumnAttribute attr = null;
|
||||
|
||||
@@ -136,6 +138,46 @@ namespace DynamORM.Mapper
|
||||
return destination;
|
||||
}
|
||||
|
||||
private IEnumerable<MemberInfo> GetAllMembers(Type type)
|
||||
{
|
||||
if (type.IsInterface)
|
||||
{
|
||||
var members = new List<MemberInfo>();
|
||||
|
||||
var considered = new List<Type>();
|
||||
var queue = new Queue<Type>();
|
||||
|
||||
considered.Add(type);
|
||||
queue.Enqueue(type);
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var subType = queue.Dequeue();
|
||||
foreach (var subInterface in subType.GetInterfaces())
|
||||
{
|
||||
if (considered.Contains(subInterface)) continue;
|
||||
|
||||
considered.Add(subInterface);
|
||||
queue.Enqueue(subInterface);
|
||||
}
|
||||
|
||||
var typeProperties = subType.GetMembers(
|
||||
BindingFlags.FlattenHierarchy
|
||||
| BindingFlags.Public
|
||||
| BindingFlags.Instance);
|
||||
|
||||
var newPropertyInfos = typeProperties
|
||||
.Where(x => !members.Contains(x));
|
||||
|
||||
members.InsertRange(0, newPropertyInfos);
|
||||
}
|
||||
|
||||
return members;
|
||||
}
|
||||
|
||||
return type.GetMembers(BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance);
|
||||
}
|
||||
|
||||
#region Type command cache
|
||||
|
||||
internal string InsertCommandText { get; set; }
|
||||
|
||||
@@ -1,55 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using DynamORM;
|
||||
using DynamORM.Mapper;
|
||||
|
||||
namespace Tester
|
||||
{
|
||||
internal class Program
|
||||
{
|
||||
[Table(Name = "dist_Distances")]
|
||||
public class Distance
|
||||
[Table(Name = "mom_Sessions")]
|
||||
internal class Session
|
||||
{
|
||||
[Column(IsKey = true)]
|
||||
public Guid StartAddress_Id { get; set; }
|
||||
|
||||
[Column(IsKey = true)]
|
||||
public Guid EndAddress_Id { get; set; }
|
||||
|
||||
[Column(IsKey = true)]
|
||||
public int VehicleType { get; set; }
|
||||
public virtual Guid ms_id { get; set; }
|
||||
|
||||
[Column]
|
||||
public int PostcodeDistanceInSecs { get; set; }
|
||||
public virtual Guid ms_mus_id { get; set; }
|
||||
|
||||
[Column]
|
||||
public decimal PostcodeDistanceInKms { get; set; }
|
||||
public virtual long ms_last_activity { get; set; }
|
||||
|
||||
[Column]
|
||||
public int IsDepotDistance { get; set; }
|
||||
public virtual int ms_type { get; set; }
|
||||
|
||||
[Column]
|
||||
public virtual string ms_desc { get; set; }
|
||||
|
||||
[Ignore]
|
||||
public virtual string ms_did { get; set; }
|
||||
}
|
||||
|
||||
private static DynamORM.DynamicDatabase GetORM()
|
||||
{
|
||||
return new DynamORM.DynamicDatabase(System.Data.SqlClient.SqlClientFactory.Instance,
|
||||
"packet size=4096;User Id=sa;Password=sa123;data source=192.168.1.9,1433;initial catalog=MOM_SIERPC_WMS_TEST;",
|
||||
DynamORM.DynamicDatabaseOptions.SingleConnection | DynamORM.DynamicDatabaseOptions.SingleTransaction |
|
||||
DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportTop);
|
||||
}
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
string conns = string.Format("Server={0};Port={1};Userid={2};Password={3};Database={4};Protocol=3;SSL=false;Pooling=true;MinPoolSize=1;MaxPoolSize=20;Encoding=UNICODE;Timeout=15;",
|
||||
"192.168.1.6", 5432, "ted", "ted123", "TED_Altom");
|
||||
|
||||
using (var db = new DynamicDatabase(Npgsql.NpgsqlFactory.Instance, conns, DynamORM.DynamicDatabaseOptions.SupportSchema | DynamORM.DynamicDatabaseOptions.SupportLimitOffset))
|
||||
Console.Out.WriteLine("Press ENTER to launch bombardment... or q and ENTER to quit.");
|
||||
while (Console.In.ReadLine() != "q")
|
||||
{
|
||||
var s = db.GetSchema<Distance>();
|
||||
Console.Out.WriteLine(s.Count);
|
||||
Console.Out.WriteLine("Bombardment...");
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
//var session = db.From(x => x.mom_Sessions.As(x.s))
|
||||
// .Where(s => s.ms_id == Guid.Empty && s.ms_mus_id == Guid.Empty)
|
||||
// .Execute<Session>()
|
||||
// .FirstOrDefault();
|
||||
//var session = db.From(x => x.mom_Sessions.As(x.s))
|
||||
// .Where(s => s.ms_id == Guid.Empty && s.ms_mus_id == Guid.Empty)
|
||||
// .Execute()
|
||||
// .FirstOrDefault();
|
||||
|
||||
DynamicTypeMap mapper = DynamORM.Mapper.DynamicMapperCache.GetMapper<Distance>();
|
||||
using (var con = db.Open())
|
||||
using (var cmd = con.CreateCommand())
|
||||
{
|
||||
Dictionary<IDbDataParameter, DynamicPropertyInvoker> parameters = new Dictionary<IDbDataParameter, DynamicPropertyInvoker>();
|
||||
db.Delete(x => x.mom_Sessions)
|
||||
.Where(s => s.ms_id == Guid.Empty && s.ms_mus_id == Guid.Empty)
|
||||
.Execute();
|
||||
|
||||
db.Insert<Distance>(new Distance[] { });
|
||||
//var session = (db.Table().Query("SELECT * FROM mom_Sessions WHERE ms_id = @0 AND ms_mus_id = @1", Guid.Empty, Guid.Empty)
|
||||
// as IEnumerable<dynamic>).FirstOrDefault();
|
||||
}
|
||||
|
||||
//db.PrepareBatchInsert<Distance>(mapper, cmd, parameters);
|
||||
}
|
||||
Console.Out.WriteLine("Done.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user