This commit is contained in:
@@ -33,31 +33,31 @@
|
|||||||
* * DYNAMORM_OMMIT_TRYPARSE - Remove TryParse helpers (also applies DYNAMORM_OMMIT_GENERICEXECUTION)
|
* * DYNAMORM_OMMIT_TRYPARSE - Remove TryParse helpers (also applies DYNAMORM_OMMIT_GENERICEXECUTION)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using DynamORM.Builders.Extensions;
|
||||||
using System.Collections;
|
using DynamORM.Builders.Implementation;
|
||||||
|
using DynamORM.Builders;
|
||||||
|
using DynamORM.Helpers.Dynamics;
|
||||||
|
using DynamORM.Helpers;
|
||||||
|
using DynamORM.Mapper;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Data;
|
using System.Collections;
|
||||||
using System.Data.Common;
|
using System.Data.Common;
|
||||||
|
using System.Data;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using DynamORM.Builders;
|
using System;
|
||||||
using DynamORM.Builders.Extensions;
|
|
||||||
using DynamORM.Builders.Implementation;
|
|
||||||
using DynamORM.Helpers;
|
|
||||||
using DynamORM.Helpers.Dynamics;
|
|
||||||
using DynamORM.Mapper;
|
|
||||||
|
|
||||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is a generated file which generates all the necessary support classes.")]
|
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is a generated file which generates all the necessary support classes.")]
|
||||||
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "This is a generated file which generates all the necessary support classes.")]
|
[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "This is a generated file which generates all the necessary support classes.")]
|
||||||
|
|
||||||
namespace DynamORM
|
namespace DynamORM
|
||||||
{
|
{
|
||||||
/// <summary>Small utility class to manage single columns.</summary>
|
/// <summary>Small utility class to manage single columns.</summary>
|
||||||
@@ -2687,11 +2687,14 @@ namespace DynamORM
|
|||||||
/// <summary>Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y).</summary>
|
/// <summary>Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y).</summary>
|
||||||
SupportLimitOffset = 0x00000040,
|
SupportLimitOffset = 0x00000040,
|
||||||
|
|
||||||
|
/// <summary>Database supports limit offset syntax (SELECT FIRST x SKIP y ... FROM ...).</summary>
|
||||||
|
SupportFirstSkip = 0x00000020,
|
||||||
|
|
||||||
/// <summary>Database support standard schema.</summary>
|
/// <summary>Database support standard schema.</summary>
|
||||||
SupportSchema = 0x00000010,
|
SupportSchema = 0x00000010,
|
||||||
|
|
||||||
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
||||||
SupportStoredProcedures = 0x00000020,
|
SupportStoredProcedures = 0x00000100,
|
||||||
|
|
||||||
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
||||||
DumpCommands = 0x01000000,
|
DumpCommands = 0x01000000,
|
||||||
@@ -4101,7 +4104,7 @@ namespace DynamORM
|
|||||||
/// <returns>Returns <c>true</c> if it does.</returns>
|
/// <returns>Returns <c>true</c> if it does.</returns>
|
||||||
public static bool IsGenericEnumerable(this Type type)
|
public static bool IsGenericEnumerable(this Type type)
|
||||||
{
|
{
|
||||||
return type.IsGenericType && type.GetInterfaces().Any(t => t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
return type.IsGenericType && type.GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Check if type implements IEnumerable<> interface.</summary>
|
/// <summary>Check if type implements IEnumerable<> interface.</summary>
|
||||||
@@ -5854,6 +5857,7 @@ namespace DynamORM
|
|||||||
IDynamicDeleteQueryBuilder Where(object conditions, bool schema = false);
|
IDynamicDeleteQueryBuilder Where(object conditions, bool schema = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Dynamic insert query builder interface.</summary>
|
/// <summary>Dynamic insert query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
|
||||||
@@ -5885,6 +5889,7 @@ namespace DynamORM
|
|||||||
IDynamicInsertQueryBuilder Insert(object o);
|
IDynamicInsertQueryBuilder Insert(object o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Dynamic query builder base interface.</summary>
|
/// <summary>Dynamic query builder base interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicQueryBuilder : IExtendedDisposable
|
public interface IDynamicQueryBuilder : IExtendedDisposable
|
||||||
@@ -5925,6 +5930,7 @@ namespace DynamORM
|
|||||||
List<Action<IParameter, IDbDataParameter>> OnCreateParameter { get; set; }
|
List<Action<IParameter, IDbDataParameter>> OnCreateParameter { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Dynamic select query builder interface.</summary>
|
/// <summary>Dynamic select query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
|
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable<object>
|
||||||
@@ -5946,7 +5952,7 @@ namespace DynamORM
|
|||||||
/// <returns>Result of a query.</returns>
|
/// <returns>Result of a query.</returns>
|
||||||
object Scalar();
|
object Scalar();
|
||||||
|
|
||||||
#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
|
#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
|
||||||
|
|
||||||
/// <summary>Returns a single result.</summary>
|
/// <summary>Returns a single result.</summary>
|
||||||
/// <typeparam name="T">Type to parse to.</typeparam>
|
/// <typeparam name="T">Type to parse to.</typeparam>
|
||||||
@@ -5954,7 +5960,7 @@ namespace DynamORM
|
|||||||
/// <returns>Result of a query.</returns>
|
/// <returns>Result of a query.</returns>
|
||||||
T ScalarAs<T>(T defaultValue = default(T));
|
T ScalarAs<T>(T defaultValue = default(T));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#region From/Join
|
#region From/Join
|
||||||
|
|
||||||
@@ -6138,6 +6144,7 @@ namespace DynamORM
|
|||||||
#endregion Top/Limit/Offset/Distinct
|
#endregion Top/Limit/Offset/Distinct
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Dynamic update query builder interface.</summary>
|
/// <summary>Dynamic update query builder interface.</summary>
|
||||||
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
/// <remarks>This interface it publically available. Implementation should be hidden.</remarks>
|
||||||
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
|
||||||
@@ -6228,6 +6235,7 @@ namespace DynamORM
|
|||||||
#endregion Where
|
#endregion Where
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Interface describing parameter info.</summary>
|
/// <summary>Interface describing parameter info.</summary>
|
||||||
public interface IParameter : IExtendedDisposable
|
public interface IParameter : IExtendedDisposable
|
||||||
{
|
{
|
||||||
@@ -6251,6 +6259,7 @@ namespace DynamORM
|
|||||||
DynamicSchemaColumn? Schema { get; set; }
|
DynamicSchemaColumn? Schema { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Interface describing table information.</summary>
|
/// <summary>Interface describing table information.</summary>
|
||||||
public interface ITableInfo : IExtendedDisposable
|
public interface ITableInfo : IExtendedDisposable
|
||||||
{
|
{
|
||||||
@@ -6267,6 +6276,7 @@ namespace DynamORM
|
|||||||
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
Dictionary<string, DynamicSchemaColumn> Schema { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Extensions
|
namespace Extensions
|
||||||
{
|
{
|
||||||
internal static class DynamicModifyBuilderExtensions
|
internal static class DynamicModifyBuilderExtensions
|
||||||
@@ -6390,6 +6400,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static class DynamicWhereQueryExtensions
|
internal static class DynamicWhereQueryExtensions
|
||||||
{
|
{
|
||||||
#region Where
|
#region Where
|
||||||
@@ -6594,6 +6605,8 @@ namespace DynamORM
|
|||||||
|
|
||||||
#endregion Where
|
#endregion Where
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Implementation
|
namespace Implementation
|
||||||
@@ -6690,6 +6703,7 @@ namespace DynamORM
|
|||||||
#endregion Where
|
#endregion Where
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Implementation of dynamic insert query builder.</summary>
|
/// <summary>Implementation of dynamic insert query builder.</summary>
|
||||||
internal class DynamicInsertQueryBuilder : DynamicModifyBuilder, IDynamicInsertQueryBuilder
|
internal class DynamicInsertQueryBuilder : DynamicModifyBuilder, IDynamicInsertQueryBuilder
|
||||||
{
|
{
|
||||||
@@ -6875,6 +6889,7 @@ namespace DynamORM
|
|||||||
#endregion IExtendedDisposable
|
#endregion IExtendedDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Base query builder for insert/update/delete statements.</summary>
|
/// <summary>Base query builder for insert/update/delete statements.</summary>
|
||||||
internal abstract class DynamicModifyBuilder : DynamicQueryBuilder
|
internal abstract class DynamicModifyBuilder : DynamicQueryBuilder
|
||||||
{
|
{
|
||||||
@@ -6914,6 +6929,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Implementation of dynamic query builder base interface.</summary>
|
/// <summary>Implementation of dynamic query builder base interface.</summary>
|
||||||
internal abstract class DynamicQueryBuilder : IDynamicQueryBuilder
|
internal abstract class DynamicQueryBuilder : IDynamicQueryBuilder
|
||||||
{
|
{
|
||||||
@@ -7813,10 +7829,10 @@ namespace DynamORM
|
|||||||
#endregion IExtendedDisposable
|
#endregion IExtendedDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Implementation of dynamic select query builder.</summary>
|
/// <summary>Implementation of dynamic select query builder.</summary>
|
||||||
internal class DynamicSelectQueryBuilder : DynamicQueryBuilder, IDynamicSelectQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
|
internal class DynamicSelectQueryBuilder : DynamicQueryBuilder, IDynamicSelectQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
|
||||||
{
|
{
|
||||||
private int? _top = null;
|
|
||||||
private int? _limit = null;
|
private int? _limit = null;
|
||||||
private int? _offset = null;
|
private int? _offset = null;
|
||||||
private bool _distinct = false;
|
private bool _distinct = false;
|
||||||
@@ -7855,17 +7871,42 @@ namespace DynamORM
|
|||||||
/// <returns>The text to execute against the underlying database.</returns>
|
/// <returns>The text to execute against the underlying database.</returns>
|
||||||
public override string CommandText()
|
public override string CommandText()
|
||||||
{
|
{
|
||||||
|
bool lused = false;
|
||||||
|
bool oused = false;
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder("SELECT");
|
StringBuilder sb = new StringBuilder("SELECT");
|
||||||
if (_distinct) sb.AppendFormat(" DISTINCT");
|
if (_distinct) sb.AppendFormat(" DISTINCT");
|
||||||
if (_top.HasValue) sb.AppendFormat(" TOP {0}", _top);
|
|
||||||
|
if (_limit.HasValue)
|
||||||
|
{
|
||||||
|
if ((Database.Options & DynamicDatabaseOptions.SupportTop) == DynamicDatabaseOptions.SupportTop)
|
||||||
|
{
|
||||||
|
sb.AppendFormat(" TOP {0}", _limit);
|
||||||
|
lused = true;
|
||||||
|
}
|
||||||
|
else if ((Database.Options & DynamicDatabaseOptions.SupportFirstSkip) == DynamicDatabaseOptions.SupportFirstSkip)
|
||||||
|
{
|
||||||
|
sb.AppendFormat(" FIRST {0}", _limit);
|
||||||
|
lused = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_offset.HasValue && (Database.Options & DynamicDatabaseOptions.SupportFirstSkip) == DynamicDatabaseOptions.SupportFirstSkip)
|
||||||
|
{
|
||||||
|
sb.AppendFormat(" SKIP {0}", _offset);
|
||||||
|
oused = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_select != null) sb.AppendFormat(" {0}", _select); else sb.Append(" *");
|
if (_select != null) sb.AppendFormat(" {0}", _select); else sb.Append(" *");
|
||||||
if (_from != null) sb.AppendFormat(" FROM {0}", _from);
|
if (_from != null) sb.AppendFormat(" FROM {0}", _from);
|
||||||
if (_join != null) sb.AppendFormat(" {0}", _join);
|
if (_join != null) sb.AppendFormat(" {0}", _join);
|
||||||
if (WhereCondition != null) sb.AppendFormat(" WHERE {0}", WhereCondition);
|
if (WhereCondition != null) sb.AppendFormat(" WHERE {0}", WhereCondition);
|
||||||
if (_groupby != null) sb.AppendFormat(" GROUP BY {0}", _groupby);
|
if (_groupby != null) sb.AppendFormat(" GROUP BY {0}", _groupby);
|
||||||
if (_orderby != null) sb.AppendFormat(" ORDER BY {0}", _orderby);
|
if (_orderby != null) sb.AppendFormat(" ORDER BY {0}", _orderby);
|
||||||
if (_limit.HasValue) sb.AppendFormat(" LIMIT {0}", _limit);
|
if (_limit.HasValue && !lused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
|
||||||
if (_offset.HasValue) sb.AppendFormat(" OFFSET {0}", _offset);
|
sb.AppendFormat(" LIMIT {0}", _limit);
|
||||||
|
if (_offset.HasValue && !oused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
|
||||||
|
sb.AppendFormat(" OFFSET {0}", _offset);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -7969,7 +8010,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
|
#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
|
||||||
|
|
||||||
/// <summary>Returns a single result.</summary>
|
/// <summary>Returns a single result.</summary>
|
||||||
/// <typeparam name="T">Type to parse to.</typeparam>
|
/// <typeparam name="T">Type to parse to.</typeparam>
|
||||||
@@ -7986,7 +8027,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endregion Execution
|
#endregion Execution
|
||||||
|
|
||||||
@@ -8877,11 +8918,7 @@ namespace DynamORM
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicSelectQueryBuilder Top(int? top)
|
public virtual IDynamicSelectQueryBuilder Top(int? top)
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportTop) != DynamicDatabaseOptions.SupportTop)
|
return Limit(top);
|
||||||
throw new NotSupportedException("Database doesn't support TOP clause.");
|
|
||||||
|
|
||||||
_top = top;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Set top if database support it.</summary>
|
/// <summary>Set top if database support it.</summary>
|
||||||
@@ -8889,7 +8926,9 @@ namespace DynamORM
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicSelectQueryBuilder Limit(int? limit)
|
public virtual IDynamicSelectQueryBuilder Limit(int? limit)
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset)
|
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset &&
|
||||||
|
(Database.Options & DynamicDatabaseOptions.SupportFirstSkip) != DynamicDatabaseOptions.SupportFirstSkip &&
|
||||||
|
(Database.Options & DynamicDatabaseOptions.SupportTop) != DynamicDatabaseOptions.SupportTop)
|
||||||
throw new NotSupportedException("Database doesn't support LIMIT clause.");
|
throw new NotSupportedException("Database doesn't support LIMIT clause.");
|
||||||
|
|
||||||
_limit = limit;
|
_limit = limit;
|
||||||
@@ -8901,7 +8940,8 @@ namespace DynamORM
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicSelectQueryBuilder Offset(int? offset)
|
public virtual IDynamicSelectQueryBuilder Offset(int? offset)
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset)
|
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset &&
|
||||||
|
(Database.Options & DynamicDatabaseOptions.SupportFirstSkip) != DynamicDatabaseOptions.SupportFirstSkip)
|
||||||
throw new NotSupportedException("Database doesn't support OFFSET clause.");
|
throw new NotSupportedException("Database doesn't support OFFSET clause.");
|
||||||
|
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
@@ -9078,6 +9118,7 @@ namespace DynamORM
|
|||||||
#endregion IExtendedDisposable
|
#endregion IExtendedDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Update query builder.</summary>
|
/// <summary>Update query builder.</summary>
|
||||||
internal class DynamicUpdateQueryBuilder : DynamicModifyBuilder, IDynamicUpdateQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
|
internal class DynamicUpdateQueryBuilder : DynamicModifyBuilder, IDynamicUpdateQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
|
||||||
{
|
{
|
||||||
@@ -9377,7 +9418,10 @@ namespace DynamORM
|
|||||||
|
|
||||||
#endregion IExtendedDisposable
|
#endregion IExtendedDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Helpers
|
namespace Helpers
|
||||||
@@ -9475,6 +9519,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Framework detection and specific implementations.</summary>
|
/// <summary>Framework detection and specific implementations.</summary>
|
||||||
public static class FrameworkTools
|
public static class FrameworkTools
|
||||||
{
|
{
|
||||||
@@ -9595,6 +9640,7 @@ namespace DynamORM
|
|||||||
#endregion GetGenericTypeArguments
|
#endregion GetGenericTypeArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Extends <see cref="IDisposable"/> interface.</summary>
|
/// <summary>Extends <see cref="IDisposable"/> interface.</summary>
|
||||||
public interface IExtendedDisposable : IDisposable
|
public interface IExtendedDisposable : IDisposable
|
||||||
{
|
{
|
||||||
@@ -9607,6 +9653,7 @@ namespace DynamORM
|
|||||||
bool IsDisposed { get; }
|
bool IsDisposed { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Extends <see cref="IExtendedDisposable"/> interface.</summary>
|
/// <summary>Extends <see cref="IExtendedDisposable"/> interface.</summary>
|
||||||
public interface IFinalizerDisposable : IExtendedDisposable
|
public interface IFinalizerDisposable : IExtendedDisposable
|
||||||
{
|
{
|
||||||
@@ -9616,6 +9663,7 @@ namespace DynamORM
|
|||||||
void Dispose(bool disposing);
|
void Dispose(bool disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Class containing useful string extensions.</summary>
|
/// <summary>Class containing useful string extensions.</summary>
|
||||||
internal static class StringExtensions
|
internal static class StringExtensions
|
||||||
{
|
{
|
||||||
@@ -9913,6 +9961,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Class contains unclassified extensions.</summary>
|
/// <summary>Class contains unclassified extensions.</summary>
|
||||||
internal static class UnclassifiedExtensions
|
internal static class UnclassifiedExtensions
|
||||||
{
|
{
|
||||||
@@ -9970,6 +10019,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Dynamics
|
namespace Dynamics
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -11167,6 +11217,7 @@ namespace DynamORM
|
|||||||
#endregion Implementation of IExtendedDisposable
|
#endregion Implementation of IExtendedDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Class that allows to use interfaces as dynamic objects.</summary>
|
/// <summary>Class that allows to use interfaces as dynamic objects.</summary>
|
||||||
/// <typeparam name="T">Type of class to proxy.</typeparam>
|
/// <typeparam name="T">Type of class to proxy.</typeparam>
|
||||||
/// <remarks>This is temporary solution. Which allows to use builders as a dynamic type.</remarks>
|
/// <remarks>This is temporary solution. Which allows to use builders as a dynamic type.</remarks>
|
||||||
@@ -11459,7 +11510,10 @@ namespace DynamORM
|
|||||||
_proxy = default(T);
|
_proxy = default(T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Mapper
|
namespace Mapper
|
||||||
@@ -11605,6 +11659,7 @@ namespace DynamORM
|
|||||||
#endregion Constructors
|
#endregion Constructors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Type cast helper.</summary>
|
/// <summary>Type cast helper.</summary>
|
||||||
public static class DynamicCast
|
public static class DynamicCast
|
||||||
{
|
{
|
||||||
@@ -11690,6 +11745,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Class with mapper cache.</summary>
|
/// <summary>Class with mapper cache.</summary>
|
||||||
public static class DynamicMapperCache
|
public static class DynamicMapperCache
|
||||||
{
|
{
|
||||||
@@ -11731,6 +11787,7 @@ namespace DynamORM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Dynamic property invoker.</summary>
|
/// <summary>Dynamic property invoker.</summary>
|
||||||
public class DynamicPropertyInvoker
|
public class DynamicPropertyInvoker
|
||||||
{
|
{
|
||||||
@@ -11743,6 +11800,9 @@ namespace DynamORM
|
|||||||
public int Ordinal { get; set; }
|
public int Ordinal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Type _arrayType;
|
||||||
|
private bool _genericEnumerable;
|
||||||
|
|
||||||
/// <summary>Gets the type of property.</summary>
|
/// <summary>Gets the type of property.</summary>
|
||||||
public Type Type { get; private set; }
|
public Type Type { get; private set; }
|
||||||
|
|
||||||
@@ -11761,6 +11821,9 @@ namespace DynamORM
|
|||||||
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
||||||
public bool Ignore { get; private set; }
|
public bool Ignore { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets a value indicating whether this instance hold data contract type.</summary>
|
||||||
|
public bool IsDataContract { get; private set; }
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicPropertyInvoker" /> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicPropertyInvoker" /> class.</summary>
|
||||||
/// <param name="property">Property info to be invoked in the future.</param>
|
/// <param name="property">Property info to be invoked in the future.</param>
|
||||||
/// <param name="attr">Column attribute if exist.</param>
|
/// <param name="attr">Column attribute if exist.</param>
|
||||||
@@ -11773,6 +11836,20 @@ namespace DynamORM
|
|||||||
|
|
||||||
Ignore = ignore != null && ignore.Length > 0;
|
Ignore = ignore != null && ignore.Length > 0;
|
||||||
|
|
||||||
|
_arrayType = Type.IsArray ? Type.GetElementType() :
|
||||||
|
Type.IsGenericEnumerable() ? Type.GetGenericArguments().First() :
|
||||||
|
Type;
|
||||||
|
|
||||||
|
_genericEnumerable = Type.IsGenericEnumerable();
|
||||||
|
|
||||||
|
IsDataContract = _arrayType.GetCustomAttributes(false).Any(x => x.GetType().Name == "DataContractAttribute");
|
||||||
|
|
||||||
|
if (_arrayType.IsArray)
|
||||||
|
throw new InvalidOperationException("Jagged arrays are not supported");
|
||||||
|
|
||||||
|
if (_arrayType.IsGenericEnumerable())
|
||||||
|
throw new InvalidOperationException("Enumerables of enumerables are not supported");
|
||||||
|
|
||||||
Column = attr;
|
Column = attr;
|
||||||
|
|
||||||
if (property.CanRead)
|
if (property.CanRead)
|
||||||
@@ -11819,43 +11896,65 @@ namespace DynamORM
|
|||||||
/// <param name="val">The value.</param>
|
/// <param name="val">The value.</param>
|
||||||
public void Set(object dest, object val)
|
public void Set(object dest, object val)
|
||||||
{
|
{
|
||||||
Type type = Nullable.GetUnderlyingType(Type) ?? Type;
|
object value = null;
|
||||||
bool nullable = Type.IsGenericType && Type.GetGenericTypeDefinition() == typeof(Nullable<>);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (val == null && type.IsValueType)
|
if (Type.IsArray || _genericEnumerable)
|
||||||
{
|
{
|
||||||
if (nullable)
|
var lst = (val as IEnumerable<object>).Select(x => GetElementVal(_arrayType, x)).ToList();
|
||||||
Setter(dest, null);
|
|
||||||
else
|
value = Array.CreateInstance(_arrayType, lst.Count);
|
||||||
Setter(dest, Activator.CreateInstance(Type));
|
|
||||||
}
|
int i = 0;
|
||||||
else if ((val == null && !type.IsValueType) || (val != null && type == val.GetType()))
|
foreach (var e in lst)
|
||||||
Setter(dest, val);
|
((Array)value).SetValue(e, i++);
|
||||||
else if (type.IsEnum && val.GetType().IsValueType)
|
|
||||||
Setter(dest, Enum.ToObject(type, val));
|
|
||||||
else if (type.IsEnum)
|
|
||||||
Setter(dest, Enum.Parse(type, val.ToString()));
|
|
||||||
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
|
||||||
Setter(dest, val.ToString());
|
|
||||||
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
|
||||||
{
|
|
||||||
Guid g;
|
|
||||||
Setter(dest, Guid.TryParse((string)val, out g) ? g : Guid.Empty);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Setter(dest, Convert.ChangeType(val, type));
|
value = GetElementVal(Type, val);
|
||||||
|
|
||||||
|
Setter(dest, value);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new InvalidCastException(
|
throw new InvalidCastException(
|
||||||
string.Format("Error trying to convert value '{0}' of type '{1}' to value of type '{2}{3}' in object of type '{4}'",
|
string.Format("Error trying to convert value '{0}' of type '{1}' to value of type '{2}' in object of type '{3}'",
|
||||||
val.ToString(), val.GetType(), type.FullName, nullable ? "(NULLABLE)" : string.Empty, dest.GetType().FullName),
|
(val ?? string.Empty).ToString(), val.GetType(), Type.FullName, dest.GetType().FullName),
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object GetElementVal(System.Type etype, object val)
|
||||||
|
{
|
||||||
|
bool nullable = etype.IsGenericType && etype.GetGenericTypeDefinition() == typeof(Nullable<>);
|
||||||
|
Type type = Nullable.GetUnderlyingType(etype) ?? etype;
|
||||||
|
|
||||||
|
if (val == null && type.IsValueType)
|
||||||
|
{
|
||||||
|
if (nullable)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return Activator.CreateInstance(Type);
|
||||||
|
}
|
||||||
|
else if ((val == null && !type.IsValueType) || (val != null && type == val.GetType()))
|
||||||
|
return val;
|
||||||
|
else if (type.IsEnum && val.GetType().IsValueType)
|
||||||
|
return Enum.ToObject(type, val);
|
||||||
|
else if (type.IsEnum)
|
||||||
|
return Enum.Parse(type, val.ToString());
|
||||||
|
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
||||||
|
return val.ToString();
|
||||||
|
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
||||||
|
{
|
||||||
|
Guid g;
|
||||||
|
return Guid.TryParse((string)val, out g) ? g : Guid.Empty;
|
||||||
|
}
|
||||||
|
else if (IsDataContract)
|
||||||
|
return val.Map(type);
|
||||||
|
else
|
||||||
|
return Convert.ChangeType(val, type);
|
||||||
|
}
|
||||||
|
|
||||||
#region Type command cache
|
#region Type command cache
|
||||||
|
|
||||||
internal ParameterSpec InsertCommandParameter { get; set; }
|
internal ParameterSpec InsertCommandParameter { get; set; }
|
||||||
@@ -11867,6 +11966,7 @@ namespace DynamORM
|
|||||||
#endregion Type command cache
|
#endregion Type command cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Represents type columnMap.</summary>
|
/// <summary>Represents type columnMap.</summary>
|
||||||
public class DynamicTypeMap
|
public class DynamicTypeMap
|
||||||
{
|
{
|
||||||
@@ -12021,6 +12121,7 @@ namespace DynamORM
|
|||||||
#endregion Type command cache
|
#endregion Type command cache
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Allows to add ignore action to property.</summary>
|
/// <summary>Allows to add ignore action to property.</summary>
|
||||||
/// <remarks>Property still get's mapped from output.</remarks>
|
/// <remarks>Property still get's mapped from output.</remarks>
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
@@ -12028,6 +12129,7 @@ namespace DynamORM
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>Allows to add table name to class.</summary>
|
/// <summary>Allows to add table name to class.</summary>
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
[AttributeUsage(AttributeTargets.Class)]
|
||||||
public class TableAttribute : Attribute
|
public class TableAttribute : Attribute
|
||||||
@@ -12044,5 +12146,9 @@ namespace DynamORM
|
|||||||
/// set this to true to get schema from type.</remarks>
|
/// set this to true to get schema from type.</remarks>
|
||||||
public bool Override { get; set; }
|
public bool Override { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <summary>Implementation of dynamic select query builder.</summary>
|
/// <summary>Implementation of dynamic select query builder.</summary>
|
||||||
internal class DynamicSelectQueryBuilder : DynamicQueryBuilder, IDynamicSelectQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
|
internal class DynamicSelectQueryBuilder : DynamicQueryBuilder, IDynamicSelectQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
|
||||||
{
|
{
|
||||||
private int? _top = null;
|
|
||||||
private int? _limit = null;
|
private int? _limit = null;
|
||||||
private int? _offset = null;
|
private int? _offset = null;
|
||||||
private bool _distinct = false;
|
private bool _distinct = false;
|
||||||
@@ -83,17 +82,42 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <returns>The text to execute against the underlying database.</returns>
|
/// <returns>The text to execute against the underlying database.</returns>
|
||||||
public override string CommandText()
|
public override string CommandText()
|
||||||
{
|
{
|
||||||
|
bool lused = false;
|
||||||
|
bool oused = false;
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder("SELECT");
|
StringBuilder sb = new StringBuilder("SELECT");
|
||||||
if (_distinct) sb.AppendFormat(" DISTINCT");
|
if (_distinct) sb.AppendFormat(" DISTINCT");
|
||||||
if (_top.HasValue) sb.AppendFormat(" TOP {0}", _top);
|
|
||||||
|
if (_limit.HasValue)
|
||||||
|
{
|
||||||
|
if ((Database.Options & DynamicDatabaseOptions.SupportTop) == DynamicDatabaseOptions.SupportTop)
|
||||||
|
{
|
||||||
|
sb.AppendFormat(" TOP {0}", _limit);
|
||||||
|
lused = true;
|
||||||
|
}
|
||||||
|
else if ((Database.Options & DynamicDatabaseOptions.SupportFirstSkip) == DynamicDatabaseOptions.SupportFirstSkip)
|
||||||
|
{
|
||||||
|
sb.AppendFormat(" FIRST {0}", _limit);
|
||||||
|
lused = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_offset.HasValue && (Database.Options & DynamicDatabaseOptions.SupportFirstSkip) == DynamicDatabaseOptions.SupportFirstSkip)
|
||||||
|
{
|
||||||
|
sb.AppendFormat(" SKIP {0}", _offset);
|
||||||
|
oused = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (_select != null) sb.AppendFormat(" {0}", _select); else sb.Append(" *");
|
if (_select != null) sb.AppendFormat(" {0}", _select); else sb.Append(" *");
|
||||||
if (_from != null) sb.AppendFormat(" FROM {0}", _from);
|
if (_from != null) sb.AppendFormat(" FROM {0}", _from);
|
||||||
if (_join != null) sb.AppendFormat(" {0}", _join);
|
if (_join != null) sb.AppendFormat(" {0}", _join);
|
||||||
if (WhereCondition != null) sb.AppendFormat(" WHERE {0}", WhereCondition);
|
if (WhereCondition != null) sb.AppendFormat(" WHERE {0}", WhereCondition);
|
||||||
if (_groupby != null) sb.AppendFormat(" GROUP BY {0}", _groupby);
|
if (_groupby != null) sb.AppendFormat(" GROUP BY {0}", _groupby);
|
||||||
if (_orderby != null) sb.AppendFormat(" ORDER BY {0}", _orderby);
|
if (_orderby != null) sb.AppendFormat(" ORDER BY {0}", _orderby);
|
||||||
if (_limit.HasValue) sb.AppendFormat(" LIMIT {0}", _limit);
|
if (_limit.HasValue && !lused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
|
||||||
if (_offset.HasValue) sb.AppendFormat(" OFFSET {0}", _offset);
|
sb.AppendFormat(" LIMIT {0}", _limit);
|
||||||
|
if (_offset.HasValue && !oused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
|
||||||
|
sb.AppendFormat(" OFFSET {0}", _offset);
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
@@ -1105,11 +1129,7 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicSelectQueryBuilder Top(int? top)
|
public virtual IDynamicSelectQueryBuilder Top(int? top)
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportTop) != DynamicDatabaseOptions.SupportTop)
|
return Limit(top);
|
||||||
throw new NotSupportedException("Database doesn't support TOP clause.");
|
|
||||||
|
|
||||||
_top = top;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Set top if database support it.</summary>
|
/// <summary>Set top if database support it.</summary>
|
||||||
@@ -1117,7 +1137,9 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicSelectQueryBuilder Limit(int? limit)
|
public virtual IDynamicSelectQueryBuilder Limit(int? limit)
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset)
|
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset &&
|
||||||
|
(Database.Options & DynamicDatabaseOptions.SupportFirstSkip) != DynamicDatabaseOptions.SupportFirstSkip &&
|
||||||
|
(Database.Options & DynamicDatabaseOptions.SupportTop) != DynamicDatabaseOptions.SupportTop)
|
||||||
throw new NotSupportedException("Database doesn't support LIMIT clause.");
|
throw new NotSupportedException("Database doesn't support LIMIT clause.");
|
||||||
|
|
||||||
_limit = limit;
|
_limit = limit;
|
||||||
@@ -1129,7 +1151,8 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicSelectQueryBuilder Offset(int? offset)
|
public virtual IDynamicSelectQueryBuilder Offset(int? offset)
|
||||||
{
|
{
|
||||||
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset)
|
if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset &&
|
||||||
|
(Database.Options & DynamicDatabaseOptions.SupportFirstSkip) != DynamicDatabaseOptions.SupportFirstSkip)
|
||||||
throw new NotSupportedException("Database doesn't support OFFSET clause.");
|
throw new NotSupportedException("Database doesn't support OFFSET clause.");
|
||||||
|
|
||||||
_offset = offset;
|
_offset = offset;
|
||||||
|
|||||||
@@ -50,11 +50,14 @@ namespace DynamORM
|
|||||||
/// <summary>Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y).</summary>
|
/// <summary>Database supports limit offset syntax (SELECT ... FROM ... LIMIT x OFFSET y).</summary>
|
||||||
SupportLimitOffset = 0x00000040,
|
SupportLimitOffset = 0x00000040,
|
||||||
|
|
||||||
|
/// <summary>Database supports limit offset syntax (SELECT FIRST x SKIP y ... FROM ...).</summary>
|
||||||
|
SupportFirstSkip = 0x00000020,
|
||||||
|
|
||||||
/// <summary>Database support standard schema.</summary>
|
/// <summary>Database support standard schema.</summary>
|
||||||
SupportSchema = 0x00000010,
|
SupportSchema = 0x00000010,
|
||||||
|
|
||||||
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
/// <summary>Database support stored procedures (EXEC procedure ...).</summary>
|
||||||
SupportStoredProcedures = 0x00000020,
|
SupportStoredProcedures = 0x00000100,
|
||||||
|
|
||||||
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
/// <summary>Debug option allowing to enable command dumps by default.</summary>
|
||||||
DumpCommands = 0x01000000,
|
DumpCommands = 0x01000000,
|
||||||
|
|||||||
@@ -1283,7 +1283,7 @@ namespace DynamORM
|
|||||||
/// <returns>Returns <c>true</c> if it does.</returns>
|
/// <returns>Returns <c>true</c> if it does.</returns>
|
||||||
public static bool IsGenericEnumerable(this Type type)
|
public static bool IsGenericEnumerable(this Type type)
|
||||||
{
|
{
|
||||||
return type.IsGenericType && type.GetInterfaces().Any(t => t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
return type.IsGenericType && type.GetInterfaces().Any(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable<>));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Check if type implements IEnumerable<> interface.</summary>
|
/// <summary>Check if type implements IEnumerable<> interface.</summary>
|
||||||
|
|||||||
@@ -27,7 +27,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@@ -45,6 +47,9 @@ namespace DynamORM.Mapper
|
|||||||
public int Ordinal { get; set; }
|
public int Ordinal { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Type _arrayType;
|
||||||
|
private bool _genericEnumerable;
|
||||||
|
|
||||||
/// <summary>Gets the type of property.</summary>
|
/// <summary>Gets the type of property.</summary>
|
||||||
public Type Type { get; private set; }
|
public Type Type { get; private set; }
|
||||||
|
|
||||||
@@ -63,6 +68,9 @@ namespace DynamORM.Mapper
|
|||||||
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
/// <summary>Gets a value indicating whether this <see cref="DynamicPropertyInvoker"/> is ignored in some cases.</summary>
|
||||||
public bool Ignore { get; private set; }
|
public bool Ignore { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>Gets a value indicating whether this instance hold data contract type.</summary>
|
||||||
|
public bool IsDataContract { get; private set; }
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="DynamicPropertyInvoker" /> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="DynamicPropertyInvoker" /> class.</summary>
|
||||||
/// <param name="property">Property info to be invoked in the future.</param>
|
/// <param name="property">Property info to be invoked in the future.</param>
|
||||||
/// <param name="attr">Column attribute if exist.</param>
|
/// <param name="attr">Column attribute if exist.</param>
|
||||||
@@ -75,6 +83,20 @@ namespace DynamORM.Mapper
|
|||||||
|
|
||||||
Ignore = ignore != null && ignore.Length > 0;
|
Ignore = ignore != null && ignore.Length > 0;
|
||||||
|
|
||||||
|
_arrayType = Type.IsArray ? Type.GetElementType() :
|
||||||
|
Type.IsGenericEnumerable() ? Type.GetGenericArguments().First() :
|
||||||
|
Type;
|
||||||
|
|
||||||
|
_genericEnumerable = Type.IsGenericEnumerable();
|
||||||
|
|
||||||
|
IsDataContract = _arrayType.GetCustomAttributes(false).Any(x => x.GetType().Name == "DataContractAttribute");
|
||||||
|
|
||||||
|
if (_arrayType.IsArray)
|
||||||
|
throw new InvalidOperationException("Jagged arrays are not supported");
|
||||||
|
|
||||||
|
if (_arrayType.IsGenericEnumerable())
|
||||||
|
throw new InvalidOperationException("Enumerables of enumerables are not supported");
|
||||||
|
|
||||||
Column = attr;
|
Column = attr;
|
||||||
|
|
||||||
if (property.CanRead)
|
if (property.CanRead)
|
||||||
@@ -121,43 +143,65 @@ namespace DynamORM.Mapper
|
|||||||
/// <param name="val">The value.</param>
|
/// <param name="val">The value.</param>
|
||||||
public void Set(object dest, object val)
|
public void Set(object dest, object val)
|
||||||
{
|
{
|
||||||
Type type = Nullable.GetUnderlyingType(Type) ?? Type;
|
object value = null;
|
||||||
bool nullable = Type.IsGenericType && Type.GetGenericTypeDefinition() == typeof(Nullable<>);
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (val == null && type.IsValueType)
|
if (Type.IsArray || _genericEnumerable)
|
||||||
{
|
{
|
||||||
if (nullable)
|
var lst = (val as IEnumerable<object>).Select(x => GetElementVal(_arrayType, x)).ToList();
|
||||||
Setter(dest, null);
|
|
||||||
else
|
value = Array.CreateInstance(_arrayType, lst.Count);
|
||||||
Setter(dest, Activator.CreateInstance(Type));
|
|
||||||
}
|
int i = 0;
|
||||||
else if ((val == null && !type.IsValueType) || (val != null && type == val.GetType()))
|
foreach (var e in lst)
|
||||||
Setter(dest, val);
|
((Array)value).SetValue(e, i++);
|
||||||
else if (type.IsEnum && val.GetType().IsValueType)
|
|
||||||
Setter(dest, Enum.ToObject(type, val));
|
|
||||||
else if (type.IsEnum)
|
|
||||||
Setter(dest, Enum.Parse(type, val.ToString()));
|
|
||||||
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
|
||||||
Setter(dest, val.ToString());
|
|
||||||
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
|
||||||
{
|
|
||||||
Guid g;
|
|
||||||
Setter(dest, Guid.TryParse((string)val, out g) ? g : Guid.Empty);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Setter(dest, Convert.ChangeType(val, type));
|
value = GetElementVal(Type, val);
|
||||||
|
|
||||||
|
Setter(dest, value);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
throw new InvalidCastException(
|
throw new InvalidCastException(
|
||||||
string.Format("Error trying to convert value '{0}' of type '{1}' to value of type '{2}{3}' in object of type '{4}'",
|
string.Format("Error trying to convert value '{0}' of type '{1}' to value of type '{2}' in object of type '{3}'",
|
||||||
val.ToString(), val.GetType(), type.FullName, nullable ? "(NULLABLE)" : string.Empty, dest.GetType().FullName),
|
(val ?? string.Empty).ToString(), val.GetType(), Type.FullName, dest.GetType().FullName),
|
||||||
ex);
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private object GetElementVal(System.Type etype, object val)
|
||||||
|
{
|
||||||
|
bool nullable = etype.IsGenericType && etype.GetGenericTypeDefinition() == typeof(Nullable<>);
|
||||||
|
Type type = Nullable.GetUnderlyingType(etype) ?? etype;
|
||||||
|
|
||||||
|
if (val == null && type.IsValueType)
|
||||||
|
{
|
||||||
|
if (nullable)
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return Activator.CreateInstance(Type);
|
||||||
|
}
|
||||||
|
else if ((val == null && !type.IsValueType) || (val != null && type == val.GetType()))
|
||||||
|
return val;
|
||||||
|
else if (type.IsEnum && val.GetType().IsValueType)
|
||||||
|
return Enum.ToObject(type, val);
|
||||||
|
else if (type.IsEnum)
|
||||||
|
return Enum.Parse(type, val.ToString());
|
||||||
|
else if (Type == typeof(string) && val.GetType() == typeof(Guid))
|
||||||
|
return val.ToString();
|
||||||
|
else if (Type == typeof(Guid) && val.GetType() == typeof(string))
|
||||||
|
{
|
||||||
|
Guid g;
|
||||||
|
return Guid.TryParse((string)val, out g) ? g : Guid.Empty;
|
||||||
|
}
|
||||||
|
else if (IsDataContract)
|
||||||
|
return val.Map(type);
|
||||||
|
else
|
||||||
|
return Convert.ChangeType(val, type);
|
||||||
|
}
|
||||||
|
|
||||||
#region Type command cache
|
#region Type command cache
|
||||||
|
|
||||||
internal ParameterSpec InsertCommandParameter { get; set; }
|
internal ParameterSpec InsertCommandParameter { get; set; }
|
||||||
|
|||||||
Reference in New Issue
Block a user