This commit is contained in:
@@ -821,9 +821,9 @@ namespace DynamORM.Builders.Implementation
|
||||
//// return null;
|
||||
|
||||
// First we need to get real column name and it's owner if exist.
|
||||
var parts = colName.Split('.')
|
||||
.Select(c => Database.StripName(c))
|
||||
.ToArray();
|
||||
var parts = colName.Split('.');
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
parts[i] = Database.StripName(parts[i]);
|
||||
|
||||
var columnName = parts.Last();
|
||||
|
||||
|
||||
@@ -898,7 +898,11 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicSelectQueryBuilder SelectColumn(params string[] columns)
|
||||
{
|
||||
return SelectColumn(columns.Select(c => DynamicColumn.ParseSelectColumn(c)).ToArray());
|
||||
var cols = new DynamicColumn[columns.Count];
|
||||
for (int i = 0; i < columns.Length; i++)
|
||||
cols[i] = DynamicColumn.ParseSelectColumn(columns[i]);
|
||||
|
||||
return SelectColumn(cols);
|
||||
}
|
||||
|
||||
#endregion Select
|
||||
@@ -919,8 +923,11 @@ namespace DynamORM.Builders.Implementation
|
||||
int index = GroupByFunc(-1, fn);
|
||||
|
||||
if (func != null)
|
||||
foreach (var f in func)
|
||||
for (int i = 0; i < func.Length; i++)
|
||||
{
|
||||
var f = func[i];
|
||||
index = GroupByFunc(index, f);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -958,8 +965,11 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicSelectQueryBuilder GroupByColumn(params DynamicColumn[] columns)
|
||||
{
|
||||
foreach (var col in columns)
|
||||
for (int i = 0; i < columns.Length; i++)
|
||||
{
|
||||
var col = columns[i];
|
||||
GroupBy(x => col.ToSQLGroupByColumn(Database));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -995,8 +1005,11 @@ namespace DynamORM.Builders.Implementation
|
||||
int index = OrderByFunc(-1, fn);
|
||||
|
||||
if (func != null)
|
||||
foreach (var f in func)
|
||||
for (int i = 0; i < func.Length; i++)
|
||||
{
|
||||
var f = func[i];
|
||||
index = OrderByFunc(index, f);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -1087,8 +1100,11 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicSelectQueryBuilder OrderByColumn(params DynamicColumn[] columns)
|
||||
{
|
||||
foreach (var col in columns)
|
||||
for (int i = 0; i < columns.Length; i++)
|
||||
{
|
||||
var col = columns[i];
|
||||
OrderBy(x => col.ToSQLOrderByColumn(Database));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@
|
||||
<Compile Include="Mapper\TableAttribute.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="DynamicExpando.cs" />
|
||||
<Compile Include="Helpers\IFinalizerDisposable.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// a method of that argument.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Node : IDynamicMetaObjectProvider, IExtendedDisposable, ISerializable
|
||||
public class Node : IDynamicMetaObjectProvider, IFinalizerDisposable, ISerializable
|
||||
{
|
||||
private DynamicParser _parser = null;
|
||||
|
||||
@@ -76,17 +76,16 @@ namespace DynamORM.Helpers.Dynamics
|
||||
}
|
||||
|
||||
// Func was cool but caused memory leaks
|
||||
private DynamicMetaObject GetBinder(Node newNode)
|
||||
private DynamicMetaObject GetBinder(Node node)
|
||||
{
|
||||
var o = (Node)this.Value;
|
||||
o.Parser.Last = newNode;
|
||||
|
||||
newNode.Parser = o.Parser;
|
||||
node.Parser = o.Parser;
|
||||
o.Parser.Last = node;
|
||||
|
||||
var p = Expression.Variable(typeof(Node), "ret");
|
||||
var exp = Expression.Block(new ParameterExpression[] { p }, Expression.Assign(p, Expression.Constant(newNode)));
|
||||
var exp = Expression.Block(new ParameterExpression[] { p }, Expression.Assign(p, Expression.Constant(node)));
|
||||
|
||||
return new MetaNode(exp, this.Restrictions, newNode);
|
||||
return new MetaNode(exp, this.Restrictions, node);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -124,7 +123,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// </returns>
|
||||
public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
|
||||
{
|
||||
return GetBinder(new GetIndex((Node)this.Value, indexes.Select(m => m.Value).ToArray()));
|
||||
return GetBinder(new GetIndex((Node)this.Value, MetaList2List(indexes)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -138,7 +137,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// </returns>
|
||||
public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
|
||||
{
|
||||
return GetBinder(new SetIndex((Node)this.Value, indexes.Select(m => m.Value).ToArray(), value.Value));
|
||||
return GetBinder(new SetIndex((Node)this.Value, MetaList2List(indexes), value.Value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -151,7 +150,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// </returns>
|
||||
public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)
|
||||
{
|
||||
return GetBinder(new Invoke((Node)this.Value, args.Select(m => m.Value).ToArray()));
|
||||
return GetBinder(new Invoke((Node)this.Value, MetaList2List(args)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -164,7 +163,7 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// </returns>
|
||||
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
|
||||
{
|
||||
return GetBinder(new Method((Node)this.Value, binder.Name, args.Select(m => m.Value).ToArray()));
|
||||
return GetBinder(new Method((Node)this.Value, binder.Name, MetaList2List(args)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -258,6 +257,17 @@ namespace DynamORM.Helpers.Dynamics
|
||||
|
||||
return new MetaNode(exp, this.Restrictions, node);
|
||||
}
|
||||
|
||||
private static object[] MetaList2List(DynamicMetaObject[] metaObjects)
|
||||
{
|
||||
if (metaObjects == null) return null;
|
||||
|
||||
object[] list = new object[metaObjects.Length];
|
||||
for (int i = 0; i < metaObjects.Length; i++)
|
||||
list[i] = metaObjects[i].Value;
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion MetaNode
|
||||
@@ -770,16 +780,17 @@ namespace DynamORM.Helpers.Dynamics
|
||||
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public override void Dispose()
|
||||
/// <param name="disposing">If set to <c>true</c> dispose object.</param>
|
||||
public override void Dispose(bool disposing)
|
||||
{
|
||||
base.Dispose();
|
||||
base.Dispose(disposing);
|
||||
|
||||
if (Right != null && Right is Node)
|
||||
if (disposing && Right != null && Right is Node)
|
||||
{
|
||||
Node n = (Node)Right;
|
||||
|
||||
if (!n.IsDisposed)
|
||||
n.Dispose();
|
||||
n.Dispose(disposing);
|
||||
|
||||
Right = null;
|
||||
}
|
||||
@@ -1007,7 +1018,15 @@ namespace DynamORM.Helpers.Dynamics
|
||||
|
||||
#endregion Implementation of IDynamicMetaObjectProvider
|
||||
|
||||
#region Implementation of IExtendedDisposable
|
||||
#region Implementation of IFinalizerDisposable
|
||||
|
||||
/// <summary>Releases unmanaged resources and performs other cleanup operations before
|
||||
/// the <see cref="DynamORM.Helpers.Dynamics.DynamicParser.Node"/> is reclaimed by
|
||||
/// garbage collection.</summary>
|
||||
~Node()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
/// <summary>Gets a value indicating whether this instance is disposed.</summary>
|
||||
public bool IsDisposed { get; private set; }
|
||||
@@ -1016,17 +1035,29 @@ namespace DynamORM.Helpers.Dynamics
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
if (Host != null && !Host.IsDisposed)
|
||||
Host.Dispose();
|
||||
|
||||
Host = null;
|
||||
|
||||
Parser = null;
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
#endregion Implementation of IExtendedDisposable
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
/// <param name="disposing">If set to <c>true</c> dispose object.</param>
|
||||
public virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
IsDisposed = true;
|
||||
|
||||
if (Host != null && !Host.IsDisposed)
|
||||
Host.Dispose();
|
||||
|
||||
Host = null;
|
||||
|
||||
Parser = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implementation of IFinalizerDisposable
|
||||
|
||||
#region Implementation of ISerializable
|
||||
|
||||
@@ -1104,10 +1135,17 @@ namespace DynamORM.Helpers.Dynamics
|
||||
|
||||
private DynamicParser(Delegate f)
|
||||
{
|
||||
foreach (var p in f.Method.GetParameters())
|
||||
// I know this can be almost a one liner
|
||||
// but it causes memory leaks when so.
|
||||
var pars = f.Method.GetParameters();
|
||||
foreach (var p in pars)
|
||||
{
|
||||
if (p.GetCustomAttributes(typeof(DynamicAttribute), true).Any())
|
||||
this._arguments.Add(new Node.Argument(p.Name) { Parser = this });
|
||||
var attrs = p.GetCustomAttributes(typeof(DynamicAttribute), true).Length;
|
||||
if (attrs != 0)
|
||||
{
|
||||
var par = new Node.Argument(p.Name) { Parser = this };
|
||||
this._arguments.Add(par);
|
||||
}
|
||||
else
|
||||
throw new ArgumentException(string.Format("Argument '{0}' must be dynamic.", p.Name));
|
||||
}
|
||||
|
||||
41
DynamORM/Helpers/IFinalizerDisposable.cs
Normal file
41
DynamORM/Helpers/IFinalizerDisposable.cs
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* DynamORM - Dynamic Object-Relational Mapping library.
|
||||
* Copyright (c) 2012, Grzegorz Russek (grzegorz.russek@gmail.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
using System;
|
||||
|
||||
namespace DynamORM.Helpers
|
||||
{
|
||||
/// <summary>Extends <see cref="IExtendedDisposable"/> interface.</summary>
|
||||
public interface IFinalizerDisposable : IExtendedDisposable
|
||||
{
|
||||
/// <summary>Performs application-defined tasks associated with
|
||||
/// freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
/// <param name="disposing">If set to <c>true</c> dispose object.</param>
|
||||
void Dispose(bool disposing);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace Tester
|
||||
{
|
||||
string test_str = string.Empty;
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
/*for (int y = 0; y < 10; y++)
|
||||
{
|
||||
string val = null;
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@@ -119,7 +119,7 @@ namespace Tester
|
||||
GC.Collect();
|
||||
|
||||
Console.Out.WriteLine("Expr: [ExpandoObject as Dict], Mem: {0}", GC.GetTotalMemory(true));
|
||||
}
|
||||
}*/
|
||||
|
||||
/*for (int y = 0; y < 10; y++)
|
||||
{
|
||||
@@ -148,7 +148,7 @@ namespace Tester
|
||||
|
||||
//using (var db = GetORM())
|
||||
{
|
||||
for (int y = 0; y < 10; y++)
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@@ -160,7 +160,7 @@ namespace Tester
|
||||
Console.Out.WriteLine("Expr: [db.Table(\"Test\").Scalar(\"SELECT id FROM Test;\")] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@@ -172,7 +172,7 @@ namespace Tester
|
||||
Console.Out.WriteLine("Expr: [db.Table(\"Test\").Scalar(columns: \"id\")] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
@@ -184,7 +184,7 @@ namespace Tester
|
||||
Console.Out.WriteLine("Expr: [db.From(x => x.Test.As(x.t)).Where(t => t.id == 1).ToList().First().val] = {0}, Mem: {1}", test_str, GC.GetTotalMemory(true));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 10; y++)
|
||||
for (int y = 0; y < 5; y++)
|
||||
{
|
||||
using (var db = GetORM())
|
||||
for (int i = 0; i < 1000; i++)
|
||||
|
||||
Reference in New Issue
Block a user