This commit is contained in:
grzegorz.russek
2017-02-19 17:42:51 +00:00
parent 0606cf2216
commit 22c94619c6
9 changed files with 647 additions and 118 deletions

View File

@@ -1341,12 +1341,15 @@ namespace DynamORM
IsDisposed = true; IsDisposed = true;
if (_command != null)
{
_command.Parameters.Clear(); _command.Parameters.Clear();
_command.Dispose(); _command.Dispose();
_command = null; _command = null;
} }
} }
}
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
@@ -4262,6 +4265,8 @@ namespace DynamORM
/// <param name="writer">Writer to which write output.</param> /// <param name="writer">Writer to which write output.</param>
/// <returns>Returns dumped <see cref="System.Data.IDbCommand"/> instance.</returns> /// <returns>Returns dumped <see cref="System.Data.IDbCommand"/> instance.</returns>
public static IDbCommand Dump(this IDbCommand command, TextWriter writer) public static IDbCommand Dump(this IDbCommand command, TextWriter writer)
{
try
{ {
writer.WriteLine("Type: {0}; Timeout: {1}; Query: {2}", command.CommandType, command.CommandTimeout, command.CommandText); writer.WriteLine("Type: {0}; Timeout: {1}; Query: {2}", command.CommandType, command.CommandTimeout, command.CommandText);
@@ -4283,6 +4288,11 @@ namespace DynamORM
writer.WriteLine(); writer.WriteLine();
} }
}
catch (NullReferenceException)
{
writer.WriteLine("Command disposed.");
}
return command; return command;
} }
@@ -4861,7 +4871,7 @@ namespace DynamORM
{ {
TValue val; TValue val;
if (key != null && dict.TryGetValue(key, out val)) if (key != null && dict != null && dict.TryGetValue(key, out val))
return val; return val;
return default(TValue); return default(TValue);
@@ -5655,8 +5665,8 @@ namespace DynamORM
{ {
TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ? TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
type.Name : mapper.Table.Name; type.Name : mapper.Table.Name;
OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ? OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Owner) ?
type.Name : mapper.Table.Name; null : mapper.Table.Owner;
} }
BuildAndCacheSchema(keys); BuildAndCacheSchema(keys);
@@ -8208,10 +8218,12 @@ namespace DynamORM
if (node is Delegate) if (node is Delegate)
{ {
using (DynamicParser p = DynamicParser.Parse((Delegate)node)) using (DynamicParser p = DynamicParser.Parse((Delegate)node))
{
node = p.Result; node = p.Result;
return Parse(node, ref columnSchema, pars, rawstr, decorate: decorate); // Intercept containers as in (x => "string") return Parse(node, ref columnSchema, pars, rawstr, decorate: decorate); // Intercept containers as in (x => "string")
} }
}
return Dispatch(node, ref columnSchema, pars, decorate, isMultiPart); return Dispatch(node, ref columnSchema, pars, decorate, isMultiPart);
} }
@@ -9716,6 +9728,7 @@ namespace DynamORM
index++; index++;
if (f == null) if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index)); throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
using (DynamicParser parser = DynamicParser.Parse(f)) using (DynamicParser parser = DynamicParser.Parse(f))
{ {
object result = parser.Result; object result = parser.Result;
@@ -10295,6 +10308,7 @@ namespace DynamORM
object result = null; object result = null;
using (DynamicParser p = DynamicParser.Parse(f)) using (DynamicParser p = DynamicParser.Parse(f))
{
result = p.Result; result = p.Result;
if (result == null) if (result == null)
@@ -10329,6 +10343,7 @@ namespace DynamORM
if (str.Contains("=")) err += " May have you used a '==' instead of a '=' operator?"; if (str.Contains("=")) err += " May have you used a '==' instead of a '=' operator?";
throw new ArgumentException(err); throw new ArgumentException(err);
} }
}
return this; return this;
} }
@@ -11428,6 +11443,37 @@ namespace DynamORM
return "{DynamicParser::Node::SetMember::Disposed}"; return "{DynamicParser::Node::SetMember::Disposed}";
return string.Format("({0}.{1} = {2})", Host.Sketch(), Name.Sketch(), Value.Sketch()); return string.Format("({0}.{1} = {2})", Host.Sketch(), Name.Sketch(), Value.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Value != null)
{
var node = Value as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
Value = null;
}
}
catch
{
}
}
base.Dispose(disposing);
}
} }
#endregion SetMember #endregion SetMember
@@ -11508,6 +11554,42 @@ namespace DynamORM
return string.Format("{0}{1}", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch()); return string.Format("{0}{1}", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Indexes != null)
{
for (int i = 0; i < Indexes.Length; i++)
{
var node = Indexes[i] as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
}
Array.Clear(Indexes, 0, Indexes.Length);
}
}
catch
{
}
Indexes = null;
}
base.Dispose(disposing);
}
} }
#endregion GetIndex #endregion GetIndex
@@ -11572,6 +11654,37 @@ namespace DynamORM
return string.Format("({0}{1} = {2})", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch(), Value.Sketch()); return string.Format("({0}{1} = {2})", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch(), Value.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Value != null)
{
var node = Value as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
Value = null;
}
}
catch
{
}
}
base.Dispose(disposing);
}
} }
#endregion SetIndex #endregion SetIndex
@@ -11636,6 +11749,42 @@ namespace DynamORM
base.GetObjectData(info, context); base.GetObjectData(info, context);
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Arguments != null)
{
for (int i = 0; i < Arguments.Length; i++)
{
var node = Arguments[i] as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
}
Array.Clear(Arguments, 0, Arguments.Length);
}
}
catch
{
}
Arguments = null;
}
base.Dispose(disposing);
}
/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary> /// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
/// <returns>A <see cref="System.String" /> that represents this instance.</returns> /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public override string ToString() public override string ToString()
@@ -11719,6 +11868,42 @@ namespace DynamORM
return string.Format("{0}.{1}{2}", Host.Sketch(), Name.Sketch(), Arguments == null ? "()" : Arguments.Sketch(brackets: "()".ToCharArray())); return string.Format("{0}.{1}{2}", Host.Sketch(), Name.Sketch(), Arguments == null ? "()" : Arguments.Sketch(brackets: "()".ToCharArray()));
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Arguments != null)
{
for (int i = 0; i < Arguments.Length; i++)
{
var node = Arguments[i] as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
}
Array.Clear(Arguments, 0, Arguments.Length);
}
}
catch
{
}
Arguments = null;
}
base.Dispose(disposing);
}
} }
#endregion Method #endregion Method
@@ -11802,17 +11987,34 @@ namespace DynamORM
{ {
base.Dispose(disposing); base.Dispose(disposing);
if (disposing && Right != null && Right is Node) if (disposing)
{
if (Left != null)
{
if (Left is Node)
{
Node n = (Node)Left;
if (!n.IsDisposed)
n.Dispose(disposing);
}
}
if (Right != null)
{
if (Right is Node)
{ {
Node n = (Node)Right; Node n = (Node)Right;
if (!n.IsDisposed) if (!n.IsDisposed)
n.Dispose(disposing); n.Dispose(disposing);
}
Right = null; Right = null;
} }
} }
} }
}
#endregion Binary #endregion Binary
@@ -11829,7 +12031,7 @@ namespace DynamORM
public ExpressionType Operation { get; private set; } public ExpressionType Operation { get; private set; }
/// <summary>Gets host of the <see cref="Node"/>.</summary> /// <summary>Gets host of the <see cref="Node"/>.</summary>
public Node Target { get { return Host; } } public Node Target { get; private set; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Unary"/> class. /// Initializes a new instance of the <see cref="Unary"/> class.
@@ -11840,6 +12042,7 @@ namespace DynamORM
: base(target) : base(target)
{ {
Operation = operation; Operation = operation;
Target = target;
} }
/// <summary> /// <summary>
@@ -11874,6 +12077,37 @@ namespace DynamORM
return string.Format("({0} {1})", Operation, Host.Sketch()); return string.Format("({0} {1})", Operation, Host.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Target != null)
{
var node = Target as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
Target = null;
}
}
catch
{
}
}
base.Dispose(disposing);
}
} }
#endregion Unary #endregion Unary
@@ -12005,6 +12239,27 @@ namespace DynamORM
Host = type == "NULL" ? null : (Node)info.GetValue("HostItem", Type.GetType(type)); Host = type == "NULL" ? null : (Node)info.GetValue("HostItem", Type.GetType(type));
} }
/// <summary>Returns whether the given node is an ancestor of this instance.</summary>
/// <param name="node">The node to test.</param>
/// <returns>True if the given node is an ancestor of this instance.</returns>
public bool IsNodeAncestor(Node node)
{
if (node != null)
{
Node parent = Host;
while (parent != null)
{
if (object.ReferenceEquals(parent, node))
return true;
parent = parent.Host;
}
}
return false;
}
/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary> /// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
/// <returns>A <see cref="System.String" /> that represents this instance.</returns> /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public override string ToString() public override string ToString()
@@ -12220,15 +12475,19 @@ namespace DynamORM
{ {
IsDisposed = true; IsDisposed = true;
if (_uncertainResult != null && _uncertainResult is Node) if (_uncertainResult != null)
{ {
if (_uncertainResult is Node)
((Node)_uncertainResult).Dispose(); ((Node)_uncertainResult).Dispose();
_uncertainResult = null; _uncertainResult = null;
} }
if (Last != null && !Last.IsDisposed) if (Last != null)
{ {
if (!Last.IsDisposed)
Last.Dispose(); Last.Dispose();
Last = null; Last = null;
} }

View File

@@ -99,7 +99,6 @@
<Compile Include="Select\ParserTests.cs" /> <Compile Include="Select\ParserTests.cs" />
<Compile Include="TestsBase.cs" /> <Compile Include="TestsBase.cs" />
<Compile Include="Select\TypedAccessTests.cs" /> <Compile Include="Select\TypedAccessTests.cs" />
<Compile Include="Select\RenamedTypedAccessTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">

View File

@@ -398,10 +398,12 @@ namespace DynamORM.Builders.Implementation
if (node is Delegate) if (node is Delegate)
{ {
using (DynamicParser p = DynamicParser.Parse((Delegate)node)) using (DynamicParser p = DynamicParser.Parse((Delegate)node))
{
node = p.Result; node = p.Result;
return Parse(node, ref columnSchema, pars, rawstr, decorate: decorate); // Intercept containers as in (x => "string") return Parse(node, ref columnSchema, pars, rawstr, decorate: decorate); // Intercept containers as in (x => "string")
} }
}
return Dispatch(node, ref columnSchema, pars, decorate, isMultiPart); return Dispatch(node, ref columnSchema, pars, decorate, isMultiPart);
} }

View File

@@ -974,6 +974,7 @@ namespace DynamORM.Builders.Implementation
index++; index++;
if (f == null) if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index)); throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
using (DynamicParser parser = DynamicParser.Parse(f)) using (DynamicParser parser = DynamicParser.Parse(f))
{ {
object result = parser.Result; object result = parser.Result;

View File

@@ -170,6 +170,7 @@ namespace DynamORM.Builders.Implementation
object result = null; object result = null;
using (DynamicParser p = DynamicParser.Parse(f)) using (DynamicParser p = DynamicParser.Parse(f))
{
result = p.Result; result = p.Result;
if (result == null) if (result == null)
@@ -204,6 +205,7 @@ namespace DynamORM.Builders.Implementation
if (str.Contains("=")) err += " May have you used a '==' instead of a '=' operator?"; if (str.Contains("=")) err += " May have you used a '==' instead of a '=' operator?";
throw new ArgumentException(err); throw new ArgumentException(err);
} }
}
return this; return this;
} }

View File

@@ -276,12 +276,15 @@ namespace DynamORM
IsDisposed = true; IsDisposed = true;
if (_command != null)
{
_command.Parameters.Clear(); _command.Parameters.Clear();
_command.Dispose(); _command.Dispose();
_command = null; _command = null;
} }
} }
}
/// <summary>Gets a value indicating whether this instance is disposed.</summary> /// <summary>Gets a value indicating whether this instance is disposed.</summary>
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }

View File

@@ -804,6 +804,8 @@ namespace DynamORM
/// <param name="writer">Writer to which write output.</param> /// <param name="writer">Writer to which write output.</param>
/// <returns>Returns dumped <see cref="System.Data.IDbCommand"/> instance.</returns> /// <returns>Returns dumped <see cref="System.Data.IDbCommand"/> instance.</returns>
public static IDbCommand Dump(this IDbCommand command, TextWriter writer) public static IDbCommand Dump(this IDbCommand command, TextWriter writer)
{
try
{ {
writer.WriteLine("Type: {0}; Timeout: {1}; Query: {2}", command.CommandType, command.CommandTimeout, command.CommandText); writer.WriteLine("Type: {0}; Timeout: {1}; Query: {2}", command.CommandType, command.CommandTimeout, command.CommandText);
@@ -825,6 +827,11 @@ namespace DynamORM
writer.WriteLine(); writer.WriteLine();
} }
}
catch (NullReferenceException)
{
writer.WriteLine("Command disposed.");
}
return command; return command;
} }
@@ -1403,7 +1410,7 @@ namespace DynamORM
{ {
TValue val; TValue val;
if (key != null && dict.TryGetValue(key, out val)) if (key != null && dict != null && dict.TryGetValue(key, out val))
return val; return val;
return default(TValue); return default(TValue);

View File

@@ -273,8 +273,8 @@ namespace DynamORM
{ {
TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ? TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
type.Name : mapper.Table.Name; type.Name : mapper.Table.Name;
OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ? OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Owner) ?
type.Name : mapper.Table.Name; null : mapper.Table.Owner;
} }
BuildAndCacheSchema(keys); BuildAndCacheSchema(keys);

View File

@@ -411,6 +411,38 @@ namespace DynamORM.Helpers.Dynamics
return "{DynamicParser::Node::SetMember::Disposed}"; return "{DynamicParser::Node::SetMember::Disposed}";
return string.Format("({0}.{1} = {2})", Host.Sketch(), Name.Sketch(), Value.Sketch()); return string.Format("({0}.{1} = {2})", Host.Sketch(), Name.Sketch(), Value.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Value != null)
{
var node = Value as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
Value = null;
}
}
catch
{
}
}
base.Dispose(disposing);
}
} }
#endregion SetMember #endregion SetMember
@@ -491,6 +523,42 @@ namespace DynamORM.Helpers.Dynamics
return string.Format("{0}{1}", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch()); return string.Format("{0}{1}", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Indexes != null)
{
for (int i = 0; i < Indexes.Length; i++)
{
var node = Indexes[i] as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
}
Array.Clear(Indexes, 0, Indexes.Length);
}
}
catch
{
}
Indexes = null;
}
base.Dispose(disposing);
}
} }
#endregion GetIndex #endregion GetIndex
@@ -555,6 +623,38 @@ namespace DynamORM.Helpers.Dynamics
return string.Format("({0}{1} = {2})", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch(), Value.Sketch()); return string.Format("({0}{1} = {2})", Host.Sketch(), Indexes == null ? "[empty]" : Indexes.Sketch(), Value.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Value != null)
{
var node = Value as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
Value = null;
}
}
catch
{
}
}
base.Dispose(disposing);
}
} }
#endregion SetIndex #endregion SetIndex
@@ -619,6 +719,42 @@ namespace DynamORM.Helpers.Dynamics
base.GetObjectData(info, context); base.GetObjectData(info, context);
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Arguments != null)
{
for (int i = 0; i < Arguments.Length; i++)
{
var node = Arguments[i] as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
}
Array.Clear(Arguments, 0, Arguments.Length);
}
}
catch
{
}
Arguments = null;
}
base.Dispose(disposing);
}
/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary> /// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
/// <returns>A <see cref="System.String" /> that represents this instance.</returns> /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public override string ToString() public override string ToString()
@@ -702,6 +838,44 @@ namespace DynamORM.Helpers.Dynamics
return string.Format("{0}.{1}{2}", Host.Sketch(), Name.Sketch(), Arguments == null ? "()" : Arguments.Sketch(brackets: "()".ToCharArray())); return string.Format("{0}.{1}{2}", Host.Sketch(), Name.Sketch(), Arguments == null ? "()" : Arguments.Sketch(brackets: "()".ToCharArray()));
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Arguments != null)
{
for (int i = 0; i < Arguments.Length; i++)
{
var node = Arguments[i] as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
}
Array.Clear(Arguments, 0, Arguments.Length);
}
}
catch
{
}
Arguments = null;
}
base.Dispose(disposing);
}
} }
#endregion Method #endregion Method
@@ -785,17 +959,34 @@ namespace DynamORM.Helpers.Dynamics
{ {
base.Dispose(disposing); base.Dispose(disposing);
if (disposing && Right != null && Right is Node) if (disposing)
{
if (Left != null)
{
if (Left is Node)
{
Node n = (Node)Left;
if (!n.IsDisposed)
n.Dispose(disposing);
}
}
if (Right != null)
{
if (Right is Node)
{ {
Node n = (Node)Right; Node n = (Node)Right;
if (!n.IsDisposed) if (!n.IsDisposed)
n.Dispose(disposing); n.Dispose(disposing);
}
Right = null; Right = null;
} }
} }
} }
}
#endregion Binary #endregion Binary
@@ -812,7 +1003,7 @@ namespace DynamORM.Helpers.Dynamics
public ExpressionType Operation { get; private set; } public ExpressionType Operation { get; private set; }
/// <summary>Gets host of the <see cref="Node"/>.</summary> /// <summary>Gets host of the <see cref="Node"/>.</summary>
public Node Target { get { return Host; } } public Node Target { get; private set; }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Unary"/> class. /// Initializes a new instance of the <see cref="Unary"/> class.
@@ -823,6 +1014,7 @@ namespace DynamORM.Helpers.Dynamics
: base(target) : base(target)
{ {
Operation = operation; Operation = operation;
Target = target;
} }
/// <summary> /// <summary>
@@ -857,6 +1049,37 @@ namespace DynamORM.Helpers.Dynamics
return string.Format("({0} {1})", Operation, Host.Sketch()); return string.Format("({0} {1})", Operation, Host.Sketch());
} }
/// <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 override void Dispose(bool disposing)
{
if (disposing)
{
try
{
if (Target != null)
{
var node = Target as Node;
if (node != null)
{
if (node.IsNodeAncestor(this))
node.Host = null;
node.Dispose(disposing);
}
Target = null;
}
}
catch
{
}
}
base.Dispose(disposing);
}
} }
#endregion Unary #endregion Unary
@@ -988,6 +1211,27 @@ namespace DynamORM.Helpers.Dynamics
Host = type == "NULL" ? null : (Node)info.GetValue("HostItem", Type.GetType(type)); Host = type == "NULL" ? null : (Node)info.GetValue("HostItem", Type.GetType(type));
} }
/// <summary>Returns whether the given node is an ancestor of this instance.</summary>
/// <param name="node">The node to test.</param>
/// <returns>True if the given node is an ancestor of this instance.</returns>
public bool IsNodeAncestor(Node node)
{
if (node != null)
{
Node parent = Host;
while (parent != null)
{
if (object.ReferenceEquals(parent, node))
return true;
parent = parent.Host;
}
}
return false;
}
/// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary> /// <summary>Returns a <see cref="System.String" /> that represents this instance.</summary>
/// <returns>A <see cref="System.String" /> that represents this instance.</returns> /// <returns>A <see cref="System.String" /> that represents this instance.</returns>
public override string ToString() public override string ToString()
@@ -1148,8 +1392,16 @@ namespace DynamORM.Helpers.Dynamics
throw new ArgumentException(string.Format("Argument '{0}' must be dynamic.", p.Name)); throw new ArgumentException(string.Format("Argument '{0}' must be dynamic.", p.Name));
} }
try
{
_uncertainResult = f.DynamicInvoke(_arguments.ToArray()); _uncertainResult = f.DynamicInvoke(_arguments.ToArray());
} }
catch (TargetInvocationException e)
{
if (e.InnerException != null) throw e.InnerException;
else throw e;
}
}
/// <summary> /// <summary>
/// Parses the dynamic lambda expression given in the form of a delegate, and returns a new instance of the /// Parses the dynamic lambda expression given in the form of a delegate, and returns a new instance of the
@@ -1203,15 +1455,19 @@ namespace DynamORM.Helpers.Dynamics
{ {
IsDisposed = true; IsDisposed = true;
if (_uncertainResult != null && _uncertainResult is Node) if (_uncertainResult != null)
{ {
if (_uncertainResult is Node)
((Node)_uncertainResult).Dispose(); ((Node)_uncertainResult).Dispose();
_uncertainResult = null; _uncertainResult = null;
} }
if (Last != null && !Last.IsDisposed) if (Last != null)
{ {
if (!Last.IsDisposed)
Last.Dispose(); Last.Dispose();
Last = null; Last = null;
} }