diff --git a/AmalgamationTool/DynamORM.Amalgamation.cs b/AmalgamationTool/DynamORM.Amalgamation.cs
index 5a7d570..9be7b50 100644
--- a/AmalgamationTool/DynamORM.Amalgamation.cs
+++ b/AmalgamationTool/DynamORM.Amalgamation.cs
@@ -1,6 +1,6 @@
-/*
+62/*
* DynamORM - Dynamic Object-Relational Mapping library.
- * Copyright (c) 2012-2015, Grzegorz Russek (grzegorz.russek@gmail.com)
+ * Copyright (c) 2012-2026, Grzegorz Russek (grzegorz.russek@gmail.com)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,6 +60,7 @@ using System;
[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.")]
+
namespace DynamORM
{
/// Cache data reader in memory.
@@ -94,7 +95,8 @@ namespace DynamORM
/// The offset row.
/// The limit to number of tows. -1 is no limit.
/// The progress delegate.
- public DynamicCachedReader(IDataReader reader, int offset = 0, int limit = -1, Func progress = null)
+ public DynamicCachedReader(IDataReader reader, int offset = 0, int limit = -1,
+ Func progress = null)
{
InitDataReader(reader, offset, limit, progress);
}
@@ -226,7 +228,8 @@ namespace DynamORM
var mapper = DynamicMapperCache.GetMapper(elementType);
if (mapper == null)
- throw new InvalidCastException(string.Format("Object type '{0}' can't be mapped.", elementType.FullName));
+ throw new InvalidCastException(
+ string.Format("Object type '{0}' can't be mapped.", elementType.FullName));
var r = new DynamicCachedReader();
r.Init(mapper.ColumnsMap.Count + 1);
@@ -238,7 +241,8 @@ namespace DynamORM
return r;
}
- private void InitDataReader(IDataReader reader, int offset = 0, int limit = -1, Func progress = null)
+ private void InitDataReader(IDataReader reader, int offset = 0, int limit = -1,
+ Func progress = null)
{
do
{
@@ -365,10 +369,15 @@ namespace DynamORM
dr[2] = column.Value.Column.NullOr(x => x.Size ?? int.MaxValue, int.MaxValue);
dr[3] = column.Value.Column.NullOr(x => x.Precision ?? 0, 0);
dr[4] = column.Value.Column.NullOr(x => x.Scale ?? 0, 0);
- dr[5] = column.Value.Column.NullOr(x => x.Type.HasValue ? x.Type.Value.ToType() : column.Value.Type, column.Value.Type);
- dr[6] = column.Value.Column.NullOr(x => x.Type ?? column.Value.Type.ToDbType(), column.Value.Type.ToDbType());
- dr[7] = column.Value.Column.NullOr(x => x.Type ?? column.Value.Type.ToDbType(), column.Value.Type.ToDbType());
- dr[8] = column.Value.Column.NullOr(x => x.IsKey, false) ? true : column.Value.Column.NullOr(x => x.AllowNull, true);
+ dr[5] = column.Value.Column.NullOr(x => x.Type.HasValue ? x.Type.Value.ToType() : column.Value.Type,
+ column.Value.Type);
+ dr[6] = column.Value.Column.NullOr(x => x.Type ?? column.Value.Type.ToDbType(),
+ column.Value.Type.ToDbType());
+ dr[7] = column.Value.Column.NullOr(x => x.Type ?? column.Value.Type.ToDbType(),
+ column.Value.Type.ToDbType());
+ dr[8] = column.Value.Column.NullOr(x => x.IsKey, false)
+ ? true
+ : column.Value.Column.NullOr(x => x.AllowNull, true);
dr[9] = column.Value.Column.NullOr(x => x.IsUnique, false);
dr[10] = column.Value.Column.NullOr(x => x.IsKey, false);
dr[11] = false;
@@ -428,7 +437,8 @@ namespace DynamORM
if (pos >= -1 && pos < _data[_currentDataPosition]._rows)
{
_data[_currentDataPosition]._position = pos;
- _data[_currentDataPosition]._cachePos = _data[_currentDataPosition]._position * _data[_currentDataPosition]._fields;
+ _data[_currentDataPosition]._cachePos =
+ _data[_currentDataPosition]._position * _data[_currentDataPosition]._fields;
}
else
throw new IndexOutOfRangeException();
@@ -487,7 +497,10 @@ namespace DynamORM
/// Gets the number of rows changed, inserted, or deleted by execution of the SQL statement.
/// The number of rows changed, inserted, or deleted; 0 if no rows were affected or the statement
/// failed; and -1 for SELECT statements.
- public int RecordsAffected { get { return _data[_currentDataPosition]._rowsAffected; } }
+ public int RecordsAffected
+ {
+ get { return _data[_currentDataPosition]._rowsAffected; }
+ }
#endregion IDataReader Members
@@ -514,7 +527,10 @@ namespace DynamORM
/// Gets the number of columns in the current row.
/// When not positioned in a valid record set, 0; otherwise, the number of columns in the current record. The default is -1.
- public int FieldCount { get { return _data[_currentDataPosition]._fields; } }
+ public int FieldCount
+ {
+ get { return _data[_currentDataPosition]._fields; }
+ }
/// Return the value of the specified field.
/// The index of the field to find.
@@ -1170,7 +1186,9 @@ namespace DynamORM
DynamicColumn ret = new DynamicColumn() { ColumnName = parts[0] };
if (parts.Length > 1)
- ret.Order = parts[1].ToLower() == "d" || parts[1].ToLower() == "desc" ? SortOrder.Desc : SortOrder.Asc;
+ ret.Order = parts[1].ToLower() == "d" || parts[1].ToLower() == "desc"
+ ? SortOrder.Desc
+ : SortOrder.Asc;
if (parts.Length > 2)
ret.Alias = parts[2];
@@ -1207,9 +1225,9 @@ namespace DynamORM
{
sb.AppendFormat("{0}({1})", Aggregate, column);
- alias = string.IsNullOrEmpty(alias) ?
- ColumnName == "*" ? Guid.NewGuid().ToString() : ColumnName :
- alias;
+ alias = string.IsNullOrEmpty(alias)
+ ? ColumnName == "*" ? Guid.NewGuid().ToString() : ColumnName
+ : alias;
}
else
sb.Append(column);
@@ -1327,17 +1345,29 @@ namespace DynamORM
/// Gets or sets the text command to run against the data source.
///
/// The text command to execute. The default value is an empty string ("").
- public string CommandText { get { return _command.CommandText; } set { _command.CommandText = value; } }
+ public string CommandText
+ {
+ get { return _command.CommandText; }
+ set { _command.CommandText = value; }
+ }
///
/// Gets or sets the wait time before terminating the attempt to execute a command and generating an error.
///
/// The time (in seconds) to wait for the command to execute. The default value is 30 seconds.
/// The property value assigned is less than 0.
- public int CommandTimeout { get { return _commandTimeout ?? _command.CommandTimeout; } set { _commandTimeout = value; } }
+ public int CommandTimeout
+ {
+ get { return _commandTimeout ?? _command.CommandTimeout; }
+ set { _commandTimeout = value; }
+ }
/// Gets or sets how the property is interpreted.
- public CommandType CommandType { get { return _command.CommandType; } set { _command.CommandType = value; } }
+ public CommandType CommandType
+ {
+ get { return _command.CommandType; }
+ set { _command.CommandType = value; }
+ }
/// Gets or sets the
/// used by this instance of the .
@@ -1361,7 +1391,8 @@ namespace DynamORM
_command.Connection = null;
}
else
- throw new InvalidOperationException("Can't assign direct IDbConnection implementation. This property accepts only DynamORM implementation of IDbConnection.");
+ throw new InvalidOperationException(
+ "Can't assign direct IDbConnection implementation. This property accepts only DynamORM implementation of IDbConnection.");
}
}
@@ -1462,7 +1493,11 @@ namespace DynamORM
/// object of a data provider executes.
/// It's does nothing, transaction is peeked from transaction
/// pool of a connection. This is only a dummy.
- public IDbTransaction Transaction { get { return null; } set { } }
+ public IDbTransaction Transaction
+ {
+ get { return null; }
+ set { }
+ }
/// Gets or sets how command results are applied to the
/// when used by the
@@ -1471,7 +1506,11 @@ namespace DynamORM
/// Both unless the command is automatically generated. Then the default is None.
/// The value entered was not one of the
/// values.
- public UpdateRowSource UpdatedRowSource { get { return _command.UpdatedRowSource; } set { _command.UpdatedRowSource = value; } }
+ public UpdateRowSource UpdatedRowSource
+ {
+ get { return _command.UpdatedRowSource; }
+ set { _command.UpdatedRowSource = value; }
+ }
#endregion IDbCommand Members
@@ -1725,10 +1764,21 @@ namespace DynamORM
public DynamicDatabaseOptions Options { get; private set; }
/// Gets or sets command timeout.
- public int? CommandTimeout { get { return _commandTimeout; } set { _commandTimeout = value; _poolStamp = DateTime.Now.Ticks; } }
+ public int? CommandTimeout
+ {
+ get { return _commandTimeout; }
+ set
+ {
+ _commandTimeout = value;
+ _poolStamp = DateTime.Now.Ticks;
+ }
+ }
/// Gets the database provider.
- public DbProviderFactory Provider { get { return _provider; } }
+ public DbProviderFactory Provider
+ {
+ get { return _provider; }
+ }
/// Gets the procedures invoker.
///
@@ -1821,7 +1871,8 @@ namespace DynamORM
{
if (_proc == null)
{
- if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures)
+ if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) !=
+ DynamicDatabaseOptions.SupportStoredProcedures)
throw new InvalidOperationException("Database connection doesn't support stored procedures.");
_proc = new DynamicProcedureInvoker(this);
@@ -1870,12 +1921,14 @@ namespace DynamORM
DbProviderFactory provider = null;
bool dispose = false;
- var pi = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty);
+ var pi = type.GetProperty("Instance",
+ BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty);
if (pi != null)
provider = (DbProviderFactory)pi.GetValue(null, null);
else
{
- var fi = type.GetField("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetField);
+ var fi = type.GetField("Instance",
+ BindingFlags.Static | BindingFlags.Public | BindingFlags.GetField);
if (fi != null)
provider = (DbProviderFactory)fi.GetValue(null);
}
@@ -1924,7 +1977,8 @@ namespace DynamORM
TransactionPool.Add(connection, new Stack());
if (!_singleConnection)
- throw new InvalidOperationException("This constructor accepts only connections with DynamicDatabaseOptions.SingleConnection option.");
+ throw new InvalidOperationException(
+ "This constructor accepts only connections with DynamicDatabaseOptions.SingleConnection option.");
}
private void InitCommon(string connectionString, DynamicDatabaseOptions options)
@@ -1932,8 +1986,10 @@ namespace DynamORM
_connectionString = connectionString;
Options = options;
- _singleConnection = (options & DynamicDatabaseOptions.SingleConnection) == DynamicDatabaseOptions.SingleConnection;
- _singleTransaction = (options & DynamicDatabaseOptions.SingleTransaction) == DynamicDatabaseOptions.SingleTransaction;
+ _singleConnection = (options & DynamicDatabaseOptions.SingleConnection) ==
+ DynamicDatabaseOptions.SingleConnection;
+ _singleTransaction = (options & DynamicDatabaseOptions.SingleTransaction) ==
+ DynamicDatabaseOptions.SingleTransaction;
DumpCommands = (options & DynamicDatabaseOptions.DumpCommands) == DynamicDatabaseOptions.DumpCommands;
TransactionPool = new Dictionary>();
@@ -1986,8 +2042,8 @@ namespace DynamORM
DynamicTable dt = null;
lock (SyncLock)
dt = TablesCache.TryGetValue(key) ??
- TablesCache.AddAndPassValue(key,
- new DynamicTable(this, table, owner, keys));
+ TablesCache.AddAndPassValue(key,
+ new DynamicTable(this, table, owner, keys));
return dt;
}
@@ -2006,8 +2062,8 @@ namespace DynamORM
DynamicTable dt = null;
lock (SyncLock)
dt = TablesCache.TryGetValue(key) ??
- TablesCache.AddAndPassValue(key,
- new DynamicTable(this, table, keys));
+ TablesCache.AddAndPassValue(key,
+ new DynamicTable(this, table, keys));
return dt;
}
@@ -2016,7 +2072,8 @@ namespace DynamORM
/// Disposed dynamic table.
internal void RemoveFromCache(DynamicTable dynamicTable)
{
- foreach (KeyValuePair item in TablesCache.Where(kvp => kvp.Value == dynamicTable).ToList())
+ foreach (KeyValuePair item in TablesCache.Where(kvp => kvp.Value == dynamicTable)
+ .ToList())
TablesCache.Remove(item.Key);
}
@@ -2147,15 +2204,16 @@ namespace DynamORM
{
try
{
- Dictionary parameters = new Dictionary();
+ Dictionary parameters =
+ new Dictionary();
if (!string.IsNullOrEmpty(mapper.InsertCommandText))
{
cmd.CommandText = mapper.InsertCommandText;
foreach (DynamicPropertyInvoker col in mapper.ColumnsMap.Values
- .Where(di => !di.Ignore && di.InsertCommandParameter != null)
- .OrderBy(di => di.InsertCommandParameter.Ordinal))
+ .Where(di => !di.Ignore && di.InsertCommandParameter != null)
+ .OrderBy(di => di.InsertCommandParameter.Ordinal))
{
IDbDataParameter para = cmd.CreateParameter();
para.ParameterName = col.InsertCommandParameter.Name;
@@ -2254,15 +2312,16 @@ namespace DynamORM
{
try
{
- Dictionary parameters = new Dictionary();
+ Dictionary parameters =
+ new Dictionary();
if (!string.IsNullOrEmpty(mapper.UpdateCommandText))
{
cmd.CommandText = mapper.UpdateCommandText;
foreach (DynamicPropertyInvoker col in mapper.ColumnsMap.Values
- .Where(di => !di.Ignore && di.UpdateCommandParameter != null)
- .OrderBy(di => di.UpdateCommandParameter.Ordinal))
+ .Where(di => !di.Ignore && di.UpdateCommandParameter != null)
+ .OrderBy(di => di.UpdateCommandParameter.Ordinal))
{
IDbDataParameter para = cmd.CreateParameter();
para.ParameterName = col.UpdateCommandParameter.Name;
@@ -2332,15 +2391,16 @@ namespace DynamORM
{
#region Update
- Dictionary parametersUp = new Dictionary();
+ Dictionary parametersUp =
+ new Dictionary();
if (!string.IsNullOrEmpty(mapper.UpdateCommandText))
{
cmdUp.CommandText = mapper.UpdateCommandText;
foreach (DynamicPropertyInvoker col in mapper.ColumnsMap.Values
- .Where(di => !di.Ignore && di.UpdateCommandParameter != null)
- .OrderBy(di => di.UpdateCommandParameter.Ordinal))
+ .Where(di => !di.Ignore && di.UpdateCommandParameter != null)
+ .OrderBy(di => di.UpdateCommandParameter.Ordinal))
{
IDbDataParameter para = cmdUp.CreateParameter();
para.ParameterName = col.UpdateCommandParameter.Name;
@@ -2357,15 +2417,16 @@ namespace DynamORM
#region Insert
- Dictionary parametersIn = new Dictionary();
+ Dictionary parametersIn =
+ new Dictionary();
if (!string.IsNullOrEmpty(mapper.InsertCommandText))
{
cmdIn.CommandText = mapper.InsertCommandText;
foreach (DynamicPropertyInvoker col in mapper.ColumnsMap.Values
- .Where(di => !di.Ignore && di.InsertCommandParameter != null)
- .OrderBy(di => di.InsertCommandParameter.Ordinal))
+ .Where(di => !di.Ignore && di.InsertCommandParameter != null)
+ .OrderBy(di => di.InsertCommandParameter.Ordinal))
{
IDbDataParameter para = cmdIn.CreateParameter();
para.ParameterName = col.InsertCommandParameter.Name;
@@ -2475,15 +2536,16 @@ namespace DynamORM
{
try
{
- Dictionary parameters = new Dictionary();
+ Dictionary parameters =
+ new Dictionary();
if (!string.IsNullOrEmpty(mapper.DeleteCommandText))
{
cmd.CommandText = mapper.DeleteCommandText;
foreach (DynamicPropertyInvoker col in mapper.ColumnsMap.Values
- .Where(di => !di.Ignore && di.DeleteCommandParameter != null)
- .OrderBy(di => di.DeleteCommandParameter.Ordinal))
+ .Where(di => !di.Ignore && di.DeleteCommandParameter != null)
+ .OrderBy(di => di.DeleteCommandParameter.Ordinal))
{
IDbDataParameter para = cmd.CreateParameter();
para.ParameterName = col.DeleteCommandParameter.Name;
@@ -2524,12 +2586,14 @@ namespace DynamORM
return affected;
}
- private void PrepareBatchInsert(DynamicTypeMap mapper, IDbCommand cmd, Dictionary parameters)
+ private void PrepareBatchInsert(DynamicTypeMap mapper, IDbCommand cmd,
+ Dictionary parameters)
{
PrepareBatchInsert(typeof(T), mapper, cmd, parameters);
}
- private void PrepareBatchInsert(Type t, DynamicTypeMap mapper, IDbCommand cmd, Dictionary parameters)
+ private void PrepareBatchInsert(Type t, DynamicTypeMap mapper, IDbCommand cmd,
+ Dictionary parameters)
{
DynamicPropertyInvoker currentprop = null;
Dictionary temp = new Dictionary();
@@ -2576,12 +2640,14 @@ namespace DynamORM
mapper.InsertCommandText = cmd.CommandText;
}
- private void PrepareBatchUpdate(DynamicTypeMap mapper, IDbCommand cmd, Dictionary parameters)
+ private void PrepareBatchUpdate(DynamicTypeMap mapper, IDbCommand cmd,
+ Dictionary parameters)
{
PrepareBatchUpdate(typeof(T), mapper, cmd, parameters);
}
- private void PrepareBatchUpdate(Type t, DynamicTypeMap mapper, IDbCommand cmd, Dictionary parameters)
+ private void PrepareBatchUpdate(Type t, DynamicTypeMap mapper, IDbCommand cmd,
+ Dictionary parameters)
{
DynamicPropertyInvoker currentprop = null;
Dictionary temp = new Dictionary();
@@ -2654,12 +2720,14 @@ namespace DynamORM
mapper.UpdateCommandText = cmd.CommandText;
}
- private void PrepareBatchDelete(DynamicTypeMap mapper, IDbCommand cmd, Dictionary parameters)
+ private void PrepareBatchDelete(DynamicTypeMap mapper, IDbCommand cmd,
+ Dictionary parameters)
{
PrepareBatchDelete(typeof(T), mapper, cmd, parameters);
}
- private void PrepareBatchDelete(Type t, DynamicTypeMap mapper, IDbCommand cmd, Dictionary parameters)
+ private void PrepareBatchDelete(Type t, DynamicTypeMap mapper, IDbCommand cmd,
+ Dictionary parameters)
{
DynamicPropertyInvoker currentprop = null;
Dictionary temp = new Dictionary();
@@ -2741,7 +2809,8 @@ namespace DynamORM
/// Number of affected rows.
public virtual int Procedure(string procName, params object[] args)
{
- if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures)
+ if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) !=
+ DynamicDatabaseOptions.SupportStoredProcedures)
throw new InvalidOperationException("Database connection desn't support stored procedures.");
using (IDbConnection con = Open())
@@ -2760,7 +2829,8 @@ namespace DynamORM
/// Number of affected rows.
public virtual int Procedure(string procName, DynamicExpando args)
{
- if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures)
+ if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) !=
+ DynamicDatabaseOptions.SupportStoredProcedures)
throw new InvalidOperationException("Database connection desn't support stored procedures.");
using (IDbConnection con = Open())
@@ -2779,7 +2849,8 @@ namespace DynamORM
/// Number of affected rows.
public virtual int Procedure(string procName, ExpandoObject args)
{
- if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures)
+ if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) !=
+ DynamicDatabaseOptions.SupportStoredProcedures)
throw new InvalidOperationException("Database connection desn't support stored procedures.");
using (IDbConnection con = Open())
@@ -2841,8 +2912,8 @@ namespace DynamORM
foreach (IDynamicQueryBuilder builder in builders)
using (IDbCommand cmd = con.CreateCommand())
ret += cmd
- .SetCommand(builder)
- .ExecuteNonQuery();
+ .SetCommand(builder)
+ .ExecuteNonQuery();
trans.Commit();
}
@@ -2936,36 +3007,37 @@ namespace DynamORM
/// Enumerator of objects expanded from query.
public virtual IEnumerable Query(string sql, params object[] args)
{
- DynamicCachedReader cache = null;
using (IDbConnection con = Open())
using (IDbCommand cmd = con.CreateCommand())
{
using (IDataReader rdr = cmd
- .SetCommand(sql)
- .AddParameters(this, args)
- .ExecuteReader())
- cache = new DynamicCachedReader(rdr);
-
- while (cache.Read())
+ .SetCommand(sql)
+ .AddParameters(this, args)
+ .ExecuteReader())
+ using (IDataReader cache = new DynamicCachedReader(rdr))
{
- dynamic val = null;
-
- // Work around to avoid yield being in try...catch block:
- // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
- try
+ while (cache.Read())
{
- val = cache.RowToDynamic();
- }
- catch (ArgumentException argex)
- {
- StringBuilder sb = new StringBuilder();
- cmd.Dump(sb);
+ dynamic val = null;
- throw new ArgumentException(string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
- argex.InnerException.NullOr(a => a, argex));
- }
+ // Work around to avoid yield being in try...catch block:
+ // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
+ try
+ {
+ val = cache.RowToDynamic();
+ }
+ catch (ArgumentException argex)
+ {
+ StringBuilder sb = new StringBuilder();
+ cmd.Dump(sb);
- yield return val;
+ throw new ArgumentException(
+ string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
+ argex.InnerException.NullOr(a => a, argex));
+ }
+
+ yield return val;
+ }
}
}
}
@@ -2975,36 +3047,35 @@ namespace DynamORM
/// Enumerator of objects expanded from query.
public virtual IEnumerable Query(IDynamicQueryBuilder builder)
{
- DynamicCachedReader cache = null;
using (IDbConnection con = Open())
using (IDbCommand cmd = con.CreateCommand())
{
using (IDataReader rdr = cmd
- .SetCommand(builder)
- .ExecuteReader())
- cache = new DynamicCachedReader(rdr);
-
- while (cache.Read())
- {
- dynamic val = null;
-
- // Work around to avoid yield being in try...catch block:
- // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
- try
+ .SetCommand(builder)
+ .ExecuteReader())
+ using (var cache = new DynamicCachedReader(rdr))
+ while (cache.Read())
{
- val = cache.RowToDynamic();
- }
- catch (ArgumentException argex)
- {
- StringBuilder sb = new StringBuilder();
- cmd.Dump(sb);
+ dynamic val = null;
- throw new ArgumentException(string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
- argex.InnerException.NullOr(a => a, argex));
- }
+ // Work around to avoid yield being in try...catch block:
+ // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
+ try
+ {
+ val = cache.RowToDynamic();
+ }
+ catch (ArgumentException argex)
+ {
+ StringBuilder sb = new StringBuilder();
+ cmd.Dump(sb);
- yield return val;
- }
+ throw new ArgumentException(
+ string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
+ argex.InnerException.NullOr(a => a, argex));
+ }
+
+ yield return val;
+ }
}
}
@@ -3024,9 +3095,9 @@ namespace DynamORM
using (IDbCommand cmd = con.CreateCommand())
{
using (IDataReader rdr = cmd
- .SetCommand(sql)
- .AddParameters(this, args)
- .ExecuteReader())
+ .SetCommand(sql)
+ .AddParameters(this, args)
+ .ExecuteReader())
return new DynamicCachedReader(rdr);
}
}
@@ -3040,8 +3111,8 @@ namespace DynamORM
using (IDbCommand cmd = con.CreateCommand())
{
using (IDataReader rdr = cmd
- .SetCommand(builder)
- .ExecuteReader())
+ .SetCommand(builder)
+ .ExecuteReader())
return new DynamicCachedReader(rdr);
}
}
@@ -3085,7 +3156,7 @@ namespace DynamORM
lock (SyncLock)
schema = Schema.TryGetValue(table.ToLower()) ??
- BuildAndCacheSchema(table, null, owner);
+ BuildAndCacheSchema(table, null, owner);
return schema;
}
@@ -3102,7 +3173,7 @@ namespace DynamORM
lock (SyncLock)
schema = Schema.TryGetValue(typeof(T).FullName) ??
- BuildAndCacheSchema(null, DynamicMapperCache.GetMapper());
+ BuildAndCacheSchema(null, DynamicMapperCache.GetMapper());
return schema;
}
@@ -3119,7 +3190,7 @@ namespace DynamORM
lock (SyncLock)
schema = Schema.TryGetValue(table.FullName) ??
- BuildAndCacheSchema(null, DynamicMapperCache.GetMapper(table));
+ BuildAndCacheSchema(null, DynamicMapperCache.GetMapper(table));
return schema;
}
@@ -3180,9 +3251,9 @@ namespace DynamORM
{
using (IDbConnection con = Open())
using (IDbCommand cmd = con.CreateCommand()
- .SetCommand(string.Format("SELECT * FROM {0}{1} WHERE 1 = 0",
- !string.IsNullOrEmpty(owner) ? string.Format("{0}.", DecorateName(owner)) : string.Empty,
- DecorateName(table))))
+ .SetCommand(string.Format("SELECT * FROM {0}{1} WHERE 1 = 0",
+ !string.IsNullOrEmpty(owner) ? string.Format("{0}.", DecorateName(owner)) : string.Empty,
+ DecorateName(table))))
return ReadSchema(cmd)
.ToList();
}
@@ -3243,21 +3314,24 @@ namespace DynamORM
return DynamicExtensions.TypeMap.TryGetNullable(type) ?? DbType.String;
}
- private Dictionary BuildAndCacheSchema(string tableName, DynamicTypeMap mapper, string owner = null)
+ private Dictionary BuildAndCacheSchema(string tableName, DynamicTypeMap mapper,
+ string owner = null)
{
Dictionary 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;
+ 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;
- bool mapperSchema = mapper != null && mapper.Table != null && (mapper.Table.Override || !databaseSchemaSupport);
+ (Options & DynamicDatabaseOptions.SupportSchema) ==
+ DynamicDatabaseOptions.SupportSchema;
+ bool mapperSchema = mapper != null && mapper.Table != null &&
+ (mapper.Table.Override || !databaseSchemaSupport);
#region Database schema
@@ -3290,7 +3364,9 @@ namespace DynamORM
return new DynamicSchemaColumn
{
Name = DynamicExtensions.Coalesce(
- v.Value.Column == null || string.IsNullOrEmpty(v.Value.Column.Name) ? null : v.Value.Column.Name,
+ v.Value.Column == null || string.IsNullOrEmpty(v.Value.Column.Name)
+ ? null
+ : v.Value.Column.Name,
col.HasValue && !string.IsNullOrEmpty(col.Value.Name) ? col.Value.Name : null,
v.Value.Name),
IsKey = DynamicExtensions.CoalesceNullable(
@@ -3298,7 +3374,9 @@ namespace DynamORM
col.HasValue ? col.Value.IsKey : false).Value,
Type = DynamicExtensions.CoalesceNullable(
v.Value.Column != null ? v.Value.Column.Type : null,
- col.HasValue ? col.Value.Type : DynamicExtensions.TypeMap.TryGetNullable(v.Value.Type) ?? DbType.String).Value,
+ col.HasValue
+ ? col.Value.Type
+ : DynamicExtensions.TypeMap.TryGetNullable(v.Value.Type) ?? DbType.String).Value,
IsUnique = DynamicExtensions.CoalesceNullable(
v.Value.Column != null ? v.Value.Column.IsUnique : null,
col.HasValue ? col.Value.IsUnique : false).Value,
@@ -3326,14 +3404,29 @@ namespace DynamORM
schema = mapper.ColumnsMap.ToDictionary(k => k.Key,
v => new DynamicSchemaColumn
{
- Name = DynamicExtensions.Coalesce(v.Value.Column == null || string.IsNullOrEmpty(v.Value.Column.Name) ? null : v.Value.Column.Name, v.Value.Name),
- IsKey = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.IsKey : false, false).Value,
- Type = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.Type : null, DynamicExtensions.TypeMap.TryGetNullable(v.Value.Type) ?? DbType.String).Value,
- IsUnique = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.IsUnique : null, false).Value,
- AllowNull = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.AllowNull : true, true).Value,
- Size = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.Size : null, 0).Value,
- Precision = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.Precision : null, 0).Value,
- Scale = DynamicExtensions.CoalesceNullable(v.Value.Column != null ? v.Value.Column.Scale : null, 0).Value,
+ Name = DynamicExtensions.Coalesce(
+ v.Value.Column == null || string.IsNullOrEmpty(v.Value.Column.Name)
+ ? null
+ : v.Value.Column.Name, v.Value.Name),
+ IsKey = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.IsKey : false, false)
+ .Value,
+ Type = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.Type : null,
+ DynamicExtensions.TypeMap.TryGetNullable(v.Value.Type) ?? DbType.String).Value,
+ IsUnique = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.IsUnique : null, false)
+ .Value,
+ AllowNull = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.AllowNull : true, true)
+ .Value,
+ Size = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.Size : null, 0).Value,
+ Precision = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.Precision : null, 0)
+ .Value,
+ Scale = DynamicExtensions
+ .CoalesceNullable(v.Value.Column != null ? v.Value.Column.Scale : null, 0).Value,
});
#endregion MapEnumerable based only on type
@@ -3377,7 +3470,11 @@ namespace DynamORM
}
/// Gets or sets parameter name format.
- public string ParameterFormat { get { return _parameterFormat; } set { _parameterFormat = value; } }
+ public string ParameterFormat
+ {
+ get { return _parameterFormat; }
+ set { _parameterFormat = value; }
+ }
/// Decorate string representing name of database object.
/// Name of database object.
@@ -3725,7 +3822,8 @@ namespace DynamORM
}
/// Dynamic expando is a simple and temporary class to resolve memory leaks inside ExpandoObject.
- public class DynamicExpando : DynamicObject, IDictionary, ICollection>, IEnumerable>, IEnumerable
+ public class DynamicExpando : DynamicObject, IDictionary, ICollection>,
+ IEnumerable>, IEnumerable
{
/// Class containing information about last accessed property of dynamic object.
public class PropertyAccess
@@ -3833,11 +3931,21 @@ namespace DynamORM
return _data.TryGetValue(key, out value);
}
- object IDictionary.this[string index] { get { return _data[index]; } set { _data[index] = value; } }
+ object IDictionary.this[string index]
+ {
+ get { return _data[index]; }
+ set { _data[index] = value; }
+ }
- ICollection IDictionary.Keys { get { return _data.Keys; } }
+ ICollection IDictionary.Keys
+ {
+ get { return _data.Keys; }
+ }
- ICollection
/// The command which failed.
public DynamicQueryException(IDbCommand command = null)
- : base(string.Format("Error executing command.{0}{1}", Environment.NewLine, command != null ? command.DumpToString() : string.Empty))
+ : base(string.Format("Error executing command.{0}{1}", Environment.NewLine,
+ command != null ? command.DumpToString() : string.Empty))
{
}
@@ -6037,7 +6196,8 @@ namespace DynamORM
/// The message.
/// The command which failed.
public DynamicQueryException(string message, IDbCommand command = null)
- : base(string.Format("{0}{1}{2}", message, Environment.NewLine, command != null ? command.DumpToString() : string.Empty))
+ : base(string.Format("{0}{1}{2}", message, Environment.NewLine,
+ command != null ? command.DumpToString() : string.Empty))
{
}
@@ -6046,7 +6206,9 @@ namespace DynamORM
/// The inner exception.
/// The command which failed.
public DynamicQueryException(Exception innerException, IDbCommand command = null)
- : base(string.Format("Error executing command.{0}{1}", Environment.NewLine, command != null ? command.DumpToString() : string.Empty), innerException)
+ : base(
+ string.Format("Error executing command.{0}{1}", Environment.NewLine,
+ command != null ? command.DumpToString() : string.Empty), innerException)
{
}
@@ -6056,7 +6218,9 @@ namespace DynamORM
/// The inner exception.
/// The command which failed.
public DynamicQueryException(string message, Exception innerException, IDbCommand command = null)
- : base(string.Format("{0}{1}{2}", message, Environment.NewLine, command != null ? command.DumpToString() : string.Empty), innerException)
+ : base(
+ string.Format("{0}{1}{2}", message, Environment.NewLine,
+ command != null ? command.DumpToString() : string.Empty), innerException)
{
}
}
@@ -6273,8 +6437,8 @@ namespace DynamORM
{
get
{
- return string.IsNullOrEmpty(TableName) ? null : string.IsNullOrEmpty(OwnerName) ?
- Database.DecorateName(TableName) :
+ return string.IsNullOrEmpty(TableName) ? null :
+ string.IsNullOrEmpty(OwnerName) ? Database.DecorateName(TableName) :
string.Format("{0}.{1}", Database.DecorateName(OwnerName), Database.DecorateName(TableName));
}
}
@@ -6321,10 +6485,12 @@ namespace DynamORM
if (mapper != null)
{
- TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
- type.Name : mapper.Table.Name;
- OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Owner) ?
- null : mapper.Table.Owner;
+ TableName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name)
+ ? type.Name
+ : mapper.Table.Name;
+ OwnerName = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Owner)
+ ? null
+ : mapper.Table.Owner;
}
BuildAndCacheSchema(keys);
@@ -6337,7 +6503,7 @@ namespace DynamORM
Dictionary schema = null;
schema = Database.GetSchema(TableType) ??
- Database.GetSchema(TableName, OwnerName);
+ Database.GetSchema(TableName, OwnerName);
#region Fill currrent table schema
@@ -6347,7 +6513,8 @@ namespace DynamORM
if (mapper != null)
{
- IEnumerable k = mapper.ColumnsMap.Where(p => p.Value.Column != null && p.Value.Column.IsKey).Select(p => p.Key);
+ IEnumerable k = mapper.ColumnsMap.Where(p => p.Value.Column != null && p.Value.Column.IsKey)
+ .Select(p => p.Key);
if (k.Count() > 0)
keys = k.ToArray();
}
@@ -6535,7 +6702,8 @@ namespace DynamORM
/// New instance.
public dynamic Insert()
{
- return new DynamicProxy(new DynamicInsertQueryBuilder(this.Database, this.FullName));
+ return new DynamicProxy(
+ new DynamicInsertQueryBuilder(this.Database, this.FullName));
}
/// Adds a record to the database. You can pass in an Anonymous object, an ,
@@ -6558,7 +6726,8 @@ namespace DynamORM
/// New instance.
public dynamic Update()
{
- return new DynamicProxy(new DynamicUpdateQueryBuilder(this.Database, this.FullName));
+ return new DynamicProxy(
+ new DynamicUpdateQueryBuilder(this.Database, this.FullName));
}
/// Updates a record in the database. You can pass in an Anonymous object, an ExpandoObject,
@@ -6596,7 +6765,8 @@ namespace DynamORM
/// New instance.
public dynamic Delete()
{
- return new DynamicProxy(new DynamicDeleteQueryBuilder(this.Database, this.FullName));
+ return new DynamicProxy(
+ new DynamicDeleteQueryBuilder(this.Database, this.FullName));
}
/// Removes a record from the database. You can pass in an Anonymous object, an ,
@@ -6632,7 +6802,8 @@ namespace DynamORM
// accepting named args only... SKEET!
if (info.ArgumentNames.Count != args.Length)
- throw new InvalidOperationException("Please use named arguments for this type of query - the column name, orderby, columns, etc");
+ throw new InvalidOperationException(
+ "Please use named arguments for this type of query - the column name, orderby, columns, etc");
string op = binder.Name;
@@ -6670,7 +6841,10 @@ namespace DynamORM
HandleTypeArgument(null, info, ref types, builder, 0);
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
- builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, 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)
@@ -6717,7 +6891,10 @@ namespace DynamORM
HandleTypeArgument(null, info, ref types, builder, 0);
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
- builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, 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)
@@ -6772,7 +6949,10 @@ namespace DynamORM
HandleTypeArgument(null, info, ref types, builder, 0);
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
- builder.Table(string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, 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)
@@ -6824,7 +7004,10 @@ namespace DynamORM
HandleTypeArgument(null, info, ref types, builder, 0);
if (!string.IsNullOrEmpty(this.TableName) && builder.Tables.Count == 0)
- builder.From(x => string.IsNullOrEmpty(this.OwnerName) ? this.TableName : string.Format("{0}.{1}", this.OwnerName, 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)
@@ -6862,31 +7045,34 @@ namespace DynamORM
break;
case "columns":
- {
- string agregate = (op == "Sum" || op == "Max" || op == "Min" || op == "Avg" || op == "Count") ?
- op.ToUpper() : null;
+ {
+ string agregate =
+ (op == "Sum" || op == "Max" || op == "Min" || op == "Avg" || op == "Count")
+ ? op.ToUpper()
+ : null;
- if (args[i] is string || args[i] is string[])
- builder.SelectColumn((args[i] as String).NullOr(s => s.Split(','), args[i] as String[])
- .Select(c =>
- {
- DynamicColumn col = DynamicColumn.ParseSelectColumn(c);
- if (string.IsNullOrEmpty(col.Aggregate))
- col.Aggregate = agregate;
+ if (args[i] is string || args[i] is string[])
+ builder.SelectColumn((args[i] as String).NullOr(s => s.Split(','), args[i] as String[])
+ .Select(c =>
+ {
+ DynamicColumn col = DynamicColumn.ParseSelectColumn(c);
+ if (string.IsNullOrEmpty(col.Aggregate))
+ col.Aggregate = agregate;
- return col;
- }).ToArray());
- else if (args[i] is DynamicColumn || args[i] is DynamicColumn[])
- builder.SelectColumn((args[i] as DynamicColumn).NullOr(c => new DynamicColumn[] { c }, args[i] as DynamicColumn[])
- .Select(c =>
- {
- if (string.IsNullOrEmpty(c.Aggregate))
- c.Aggregate = agregate;
+ return col;
+ }).ToArray());
+ else if (args[i] is DynamicColumn || args[i] is DynamicColumn[])
+ builder.SelectColumn((args[i] as DynamicColumn)
+ .NullOr(c => new DynamicColumn[] { c }, args[i] as DynamicColumn[])
+ .Select(c =>
+ {
+ if (string.IsNullOrEmpty(c.Aggregate))
+ c.Aggregate = agregate;
- return c;
- }).ToArray());
- else goto default;
- }
+ return c;
+ }).ToArray());
+ else goto default;
+ }
break;
@@ -6921,7 +7107,7 @@ namespace DynamORM
result = (int)(long)result;
}
else if (op == "Sum" || op == "Max" ||
- op == "Min" || op == "Avg" || op == "Count")
+ op == "Min" || op == "Avg" || op == "Count")
{
if (!builder.HasSelectColumns)
throw new InvalidOperationException("You must select one column to agregate.");
@@ -6941,9 +7127,11 @@ namespace DynamORM
// Be sure to sort by DESC on selected columns
if (justOne && !(op == "Last"))
{
- if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
+ if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) ==
+ DynamicDatabaseOptions.SupportLimitOffset)
builder.Limit(1);
- else if ((Database.Options & DynamicDatabaseOptions.SupportTop) == DynamicDatabaseOptions.SupportTop)
+ else if ((Database.Options & DynamicDatabaseOptions.SupportTop) ==
+ DynamicDatabaseOptions.SupportTop)
builder.Top(1);
}
@@ -6970,9 +7158,9 @@ namespace DynamORM
if (types != null)
{
if (types.Count == 1)
- result = justOne ?
- result.Map(types[0]) :
- ((IEnumerable)result).MapEnumerable(types[0]);
+ result = justOne
+ ? result.Map(types[0])
+ : ((IEnumerable)result).MapEnumerable(types[0]);
// TODO: Dictionaries
}
@@ -6982,7 +7170,8 @@ namespace DynamORM
return result;
}
- private void HandleTypeArgument(object[] args, CallInfo info, ref IList types, T builder, int i) where T : DynamicQueryBuilder
+ private void HandleTypeArgument(object[] args, CallInfo info, ref IList types, T builder, int i)
+ where T : DynamicQueryBuilder
{
if (args != null)
{
@@ -7057,7 +7246,8 @@ namespace DynamORM
/// One of the values.
/// This action is invoked when transaction is disposed.
/// Pass custom transaction parameters.
- internal DynamicTransaction(DynamicDatabase db, DynamicConnection con, bool singleTransaction, IsolationLevel? il, Action disposed, object customParams)
+ internal DynamicTransaction(DynamicDatabase db, DynamicConnection con, bool singleTransaction,
+ IsolationLevel? il, Action disposed, object customParams)
{
_db = db;
_con = con;
@@ -7079,22 +7269,28 @@ namespace DynamORM
{
if (customParams != null)
{
- MethodInfo mi = _con.Connection.GetType().GetMethods().Where(m => m.GetParameters().Count() == 1 && m.GetParameters().First().ParameterType == customParams.GetType()).FirstOrDefault();
+ MethodInfo mi = _con.Connection.GetType().GetMethods().Where(m =>
+ m.GetParameters().Count() == 1 &&
+ m.GetParameters().First().ParameterType == customParams.GetType()).FirstOrDefault();
if (mi != null)
{
- _db.TransactionPool[_con.Connection].Push((IDbTransaction)mi.Invoke(_con.Connection, new object[] { customParams, }));
+ _db.TransactionPool[_con.Connection]
+ .Push((IDbTransaction)mi.Invoke(_con.Connection, new object[] { customParams, }));
if (_db.DumpCommands && _db.DumpCommandDelegate != null)
_db.DumpCommandDelegate(null, "BEGIN TRAN [CUSTOM ARGS]");
}
else
- throw new MissingMethodException(string.Format("Method 'BeginTransaction' accepting parameter of type '{0}' in '{1}' not found.",
+ throw new MissingMethodException(string.Format(
+ "Method 'BeginTransaction' accepting parameter of type '{0}' in '{1}' not found.",
customParams.GetType().FullName, _con.Connection.GetType().FullName));
}
else
{
_db.TransactionPool[_con.Connection]
- .Push(il.HasValue ? _con.Connection.BeginTransaction(il.Value) : _con.Connection.BeginTransaction());
+ .Push(il.HasValue
+ ? _con.Connection.BeginTransaction(il.Value)
+ : _con.Connection.BeginTransaction());
if (_db.DumpCommands && _db.DumpCommandDelegate != null)
_db.DumpCommandDelegate(null, "BEGIN TRAN");
@@ -7187,13 +7383,16 @@ namespace DynamORM
}
/// Gets a value indicating whether this instance is disposed.
- public bool IsDisposed { get { return !_isOperational; } }
+ public bool IsDisposed
+ {
+ get { return !_isOperational; }
+ }
#endregion IExtendedDisposable Members
}
namespace Builders
- {
+ {
/// Dynamic delete query builder interface.
/// This interface it publicly available. Implementation should be hidden.
public interface IDynamicDeleteQueryBuilder : IDynamicQueryBuilder
@@ -7201,7 +7400,7 @@ namespace DynamORM
/// Execute this builder.
/// Result of an execution..
int Execute();
-
+
///
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
@@ -7213,25 +7412,25 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicDeleteQueryBuilder Where(Func func);
-
+
/// Add where condition.
/// Condition column with operator and value.
/// Builder instance.
IDynamicDeleteQueryBuilder Where(DynamicColumn column);
-
+
/// Add where condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
IDynamicDeleteQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value);
-
+
/// Add where condition.
/// Condition column.
/// Condition value.
/// Builder instance.
IDynamicDeleteQueryBuilder Where(string column, object value);
-
+
/// Add where condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
@@ -7239,7 +7438,7 @@ namespace DynamORM
/// Builder instance.
IDynamicDeleteQueryBuilder Where(object conditions, bool schema = false);
}
-
+
/// Dynamic insert query builder interface.
/// This interface it publicly available. Implementation should be hidden.
public interface IDynamicInsertQueryBuilder : IDynamicQueryBuilder
@@ -7247,7 +7446,7 @@ namespace DynamORM
/// Execute this builder.
/// Result of an execution..
int Execute();
-
+
///
/// Specifies the columns to insert using the dynamic lambda expressions given. Each expression correspond to one
/// column, and can:
@@ -7258,59 +7457,59 @@ namespace DynamORM
/// The specifications.
/// This instance to permit chaining.
IDynamicInsertQueryBuilder Values(Func fn, params Func[] func);
-
+
/// Add insert fields.
/// Insert column.
/// Insert value.
/// Builder instance.
IDynamicInsertQueryBuilder Insert(string column, object value);
-
+
/// Add insert fields.
/// Set insert value as properties and values of an object.
/// Builder instance.
IDynamicInsertQueryBuilder Insert(object o);
}
-
+
/// Dynamic query builder base interface.
/// This interface it publicly available. Implementation should be hidden.
public interface IDynamicQueryBuilder : IExtendedDisposable
{
/// Gets instance.
DynamicDatabase Database { get; }
-
+
/// Gets tables information.
IList Tables { get; }
-
+
/// Gets the tables used in this builder.
IDictionary Parameters { get; }
-
+
/// Gets or sets a value indicating whether add virtual parameters.
bool VirtualMode { get; set; }
-
+
/// Gets a value indicating whether database supports standard schema.
bool SupportSchema { get; }
-
+
/// Fill command with query.
/// Command to fill.
/// Filled instance of .
IDbCommand FillCommand(IDbCommand command);
-
+
///
/// Generates the text this command will execute against the underlying database.
///
/// The text to execute against the underlying database.
/// This method must be override by derived classes.
string CommandText();
-
+
/// Gets or sets the on create temporary parameter actions.
/// This is exposed to allow setting schema of column.
List> OnCreateTemporaryParameter { get; set; }
-
+
/// Gets or sets the on create real parameter actions.
/// This is exposed to allow modification of parameter.
List> OnCreateParameter { get; set; }
}
-
+
/// Dynamic select query builder interface.
/// This interface it publicly available. Implementation should be hidden.
public interface IDynamicSelectQueryBuilder : IDynamicQueryBuilder ////, IEnumerable
@@ -7318,32 +7517,32 @@ namespace DynamORM
/// Execute this builder.
/// Enumerator of objects expanded from query.
IEnumerable Execute();
-
+
/// Execute this builder and map to given type.
/// Type of object to map on.
/// Enumerator of objects expanded from query.
IEnumerable Execute() where T : class;
-
+
/// Execute this builder as a data reader.
/// Action containing reader.
void ExecuteDataReader(Action reader);
-
+
/// Returns a single result.
/// Result of a query.
object Scalar();
-
- #if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
-
+
+#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
+
/// Returns a single result.
/// Type to parse to.
/// Default value.
/// Result of a query.
T ScalarAs(T defaultValue = default(T));
-
- #endif
-
+
+#endif
+
#region From/Join
-
+
///
/// Adds to the 'From' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -7356,7 +7555,7 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder From(Func fn, params Func[] func);
-
+
///
/// Adds to the 'Join' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -7374,11 +7573,11 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder Join(params Func[] func);
-
+
#endregion From/Join
-
+
#region Where
-
+
///
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
@@ -7390,36 +7589,36 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder Where(Func func);
-
+
/// Add where condition.
/// Condition column with operator and value.
/// Builder instance.
IDynamicSelectQueryBuilder Where(DynamicColumn column);
-
+
/// Add where condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
IDynamicSelectQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value);
-
+
/// Add where condition.
/// Condition column.
/// Condition value.
/// Builder instance.
IDynamicSelectQueryBuilder Where(string column, object value);
-
+
/// Add where condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
/// aren't keys.
/// Builder instance.
IDynamicSelectQueryBuilder Where(object conditions, bool schema = false);
-
+
#endregion Where
-
+
#region Select
-
+
///
/// Adds to the 'Select' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -7433,23 +7632,23 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder Select(Func fn, params Func[] func);
-
+
/// Add select columns.
/// Columns to add to object.
/// Builder instance.
IDynamicSelectQueryBuilder SelectColumn(params DynamicColumn[] columns);
-
+
/// Add select columns.
/// Columns to add to object.
/// Column format consist of Column Name, Alias and
/// Aggregate function in this order separated by ':'.
/// Builder instance.
IDynamicSelectQueryBuilder SelectColumn(params string[] columns);
-
+
#endregion Select
-
+
#region GroupBy
-
+
///
/// Adds to the 'Group By' clause the contents obtained from from parsing the dynamic lambda expression given.
///
@@ -7457,23 +7656,23 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder GroupBy(Func fn, params Func[] func);
-
+
/// Add select columns.
/// Columns to group by.
/// Builder instance.
IDynamicSelectQueryBuilder GroupByColumn(params DynamicColumn[] columns);
-
+
/// Add select columns.
/// Columns to group by.
/// Column format consist of Column Name and
/// Alias in this order separated by ':'.
/// Builder instance.
IDynamicSelectQueryBuilder GroupByColumn(params string[] columns);
-
+
#endregion GroupBy
-
+
#region Having
-
+
///
/// Adds to the 'Having' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, Having the specific customs virtual methods supported by the parser are used
@@ -7485,36 +7684,36 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder Having(Func func);
-
+
/// Add Having condition.
/// Condition column with operator and value.
/// Builder instance.
IDynamicSelectQueryBuilder Having(DynamicColumn column);
-
+
/// Add Having condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
IDynamicSelectQueryBuilder Having(string column, DynamicColumn.CompareOperator op, object value);
-
+
/// Add Having condition.
/// Condition column.
/// Condition value.
/// Builder instance.
IDynamicSelectQueryBuilder Having(string column, object value);
-
+
/// Add Having condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
/// aren't keys.
/// Builder instance.
IDynamicSelectQueryBuilder Having(object conditions, bool schema = false);
-
+
#endregion Having
-
+
#region OrderBy
-
+
///
/// Adds to the 'Order By' clause the contents obtained from from parsing the dynamic lambda expression given. It
/// accepts a multipart column specification followed by an optional Ascending() or Descending() virtual methods
@@ -7525,46 +7724,46 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicSelectQueryBuilder OrderBy(Func fn, params Func[] func);
-
+
/// Add select columns.
/// Columns to order by.
/// Builder instance.
IDynamicSelectQueryBuilder OrderByColumn(params DynamicColumn[] columns);
-
+
/// Add select columns.
/// Columns to order by.
/// Column format consist of Column Name and
/// Alias in this order separated by ':'.
/// Builder instance.
IDynamicSelectQueryBuilder OrderByColumn(params string[] columns);
-
+
#endregion OrderBy
-
+
#region Top/Limit/Offset/Distinct
-
+
/// Set top if database support it.
/// How many objects select.
/// Builder instance.
IDynamicSelectQueryBuilder Top(int? top);
-
+
/// Set top if database support it.
/// How many objects select.
/// Builder instance.
IDynamicSelectQueryBuilder Limit(int? limit);
-
+
/// Set top if database support it.
/// How many objects skip selecting.
/// Builder instance.
IDynamicSelectQueryBuilder Offset(int? offset);
-
+
/// Set distinct mode.
/// Distinct mode.
/// Builder instance.
IDynamicSelectQueryBuilder Distinct(bool distinct = true);
-
+
#endregion Top/Limit/Offset/Distinct
}
-
+
/// Dynamic update query builder interface.
/// This interface it publicly available. Implementation should be hidden.
public interface IDynamicUpdateQueryBuilder : IDynamicQueryBuilder
@@ -7572,24 +7771,24 @@ namespace DynamORM
/// Execute this builder.
/// Result of an execution..
int Execute();
-
+
#region Update
-
+
/// Add update value or where condition using schema.
/// Update or where column name.
/// Column value.
/// Builder instance.
IDynamicUpdateQueryBuilder Update(string column, object value);
-
+
/// Add update values and where condition columns using schema.
/// Set values or conditions as properties and values of an object.
/// Builder instance.
IDynamicUpdateQueryBuilder Update(object conditions);
-
+
#endregion Update
-
+
#region Values
-
+
///
/// Specifies the columns to update using the dynamic lambda expressions given. Each expression correspond to one
/// column, and can:
@@ -7599,22 +7798,22 @@ namespace DynamORM
/// The specifications.
/// This instance to permit chaining.
IDynamicUpdateQueryBuilder Set(params Func[] func);
-
+
/// Add insert fields.
/// Insert column.
/// Insert value.
/// Builder instance.
IDynamicUpdateQueryBuilder Values(string column, object value);
-
+
/// Add insert fields.
/// Set insert value as properties and values of an object.
/// Builder instance.
IDynamicUpdateQueryBuilder Values(object o);
-
+
#endregion Values
-
+
#region Where
-
+
///
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
@@ -7626,102 +7825,104 @@ namespace DynamORM
/// The specification.
/// This instance to permit chaining.
IDynamicUpdateQueryBuilder Where(Func func);
-
+
/// Add where condition.
/// Condition column with operator and value.
/// Builder instance.
IDynamicUpdateQueryBuilder Where(DynamicColumn column);
-
+
/// Add where condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
IDynamicUpdateQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value);
-
+
/// Add where condition.
/// Condition column.
/// Condition value.
/// Builder instance.
IDynamicUpdateQueryBuilder Where(string column, object value);
-
+
/// Add where condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
/// aren't keys.
/// Builder instance.
IDynamicUpdateQueryBuilder Where(object conditions, bool schema = false);
-
+
#endregion Where
}
-
+
/// Interface describing parameter info.
public interface IParameter : IExtendedDisposable
{
/// Gets the parameter position in command.
/// Available after filling the command.
int Ordinal { get; }
-
+
/// Gets the parameter temporary name.
string Name { get; }
-
+
/// Gets or sets the parameter value.
object Value { get; set; }
-
+
/// Gets or sets a value indicating whether name of temporary parameter is well known.
bool WellKnown { get; set; }
-
+
/// Gets or sets a value indicating whether this is virtual.
bool Virtual { get; set; }
-
+
/// Gets or sets the parameter schema information.
DynamicSchemaColumn? Schema { get; set; }
}
-
+
/// Interface describing table information.
public interface ITableInfo : IExtendedDisposable
{
/// Gets table owner name.
string Owner { get; }
-
+
/// Gets table name.
string Name { get; }
-
+
/// Gets table alias.
string Alias { get; }
-
+
/// Gets table no lock status.
bool NoLock { get; }
-
+
/// Gets table schema.
Dictionary Schema { get; }
}
namespace Extensions
- {
+ {
internal static class DynamicHavingQueryExtensions
{
#region Where
-
- internal static T InternalHaving(this T builder, Func func) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
+
+ internal static T InternalHaving(this T builder, Func func)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
{
return builder.InternalHaving(false, false, func);
}
-
- internal static T InternalHaving(this T builder, bool addBeginBrace, bool addEndBrace, Func func) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
+
+ internal static T InternalHaving(this T builder, bool addBeginBrace, bool addEndBrace,
+ Func func) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
{
if (func == null) throw new ArgumentNullException("Array of functions cannot be null.");
-
+
using (DynamicParser parser = DynamicParser.Parse(func))
{
string condition = null;
bool and = true;
-
+
object result = parser.Result;
if (result is string)
{
condition = (string)result;
-
+
if (condition.ToUpper().IndexOf("OR") == 0)
{
and = false;
@@ -7735,113 +7936,163 @@ namespace DynamORM
else
{
// Intercepting the 'x => x.And()' and 'x => x.Or()' virtual methods...
- if (result is DynamicParser.Node.Method && ((DynamicParser.Node.Method)result).Host is DynamicParser.Node.Argument)
+ if (result is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)result).Host is DynamicParser.Node.Argument)
{
DynamicParser.Node.Method node = (DynamicParser.Node.Method)result;
string name = node.Name.ToUpper();
if (name == "AND" || name == "OR")
{
object[] args = ((DynamicParser.Node.Method)node).Arguments;
- if (args == null) throw new ArgumentNullException("arg", string.Format("{0} is not a parameterless method.", name));
- if (args.Length != 1) throw new ArgumentException(string.Format("{0} requires one and only one parameter: {1}.", name, args.Sketch()));
-
+ if (args == null)
+ throw new ArgumentNullException("arg",
+ string.Format("{0} is not a parameterless method.", name));
+ if (args.Length != 1)
+ throw new ArgumentException(string.Format(
+ "{0} requires one and only one parameter: {1}.", name, args.Sketch()));
+
and = name == "AND" ? true : false;
result = args[0];
}
}
-
+
// Just parsing the contents now...
condition = builder.Parse(result, pars: builder.Parameters).Validated("Where condition");
}
-
+
if (addBeginBrace) builder.HavingOpenBracketsCount++;
if (addEndBrace) builder.HavingOpenBracketsCount--;
-
+
if (builder.HavingCondition == null)
builder.HavingCondition = string.Format("{0}{1}{2}",
addBeginBrace ? "(" : string.Empty, condition, addEndBrace ? ")" : string.Empty);
else
- builder.HavingCondition = string.Format("{0} {1} {2}{3}{4}", builder.HavingCondition, and ? "AND" : "OR",
+ builder.HavingCondition = string.Format("{0} {1} {2}{3}{4}", builder.HavingCondition,
+ and ? "AND" : "OR",
addBeginBrace ? "(" : string.Empty, condition, addEndBrace ? ")" : string.Empty);
}
-
+
return builder;
}
-
- internal static T InternalHaving(this T builder, DynamicColumn column) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
+
+ internal static T InternalHaving(this T builder, DynamicColumn column)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
{
bool virt = builder.VirtualMode;
if (column.VirtualColumn.HasValue)
builder.VirtualMode = column.VirtualColumn.Value;
-
+
Action modParam = (p) =>
{
if (column.Schema.HasValue)
p.Schema = column.Schema;
-
+
if (!p.Schema.HasValue)
p.Schema = column.Schema ?? builder.GetColumnFromSchema(column.ColumnName);
};
-
+
builder.CreateTemporaryParameterAction(modParam);
-
+
// It's kind of uglu, but... well it works.
if (column.Or)
switch (column.Operator)
{
default:
- case DynamicColumn.CompareOperator.Eq: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) == column.Value)); break;
- case DynamicColumn.CompareOperator.Not: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) != column.Value)); break;
- case DynamicColumn.CompareOperator.Like: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).Like(column.Value))); break;
- case DynamicColumn.CompareOperator.NotLike: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value))); break;
- case DynamicColumn.CompareOperator.In: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).In(column.Value))); break;
- case DynamicColumn.CompareOperator.Lt: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) < column.Value)); break;
- case DynamicColumn.CompareOperator.Lte: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) <= column.Value)); break;
- case DynamicColumn.CompareOperator.Gt: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) > column.Value)); break;
- case DynamicColumn.CompareOperator.Gte: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) >= column.Value)); break;
- case DynamicColumn.CompareOperator.Between: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).Between(column.Value))); break;
+ case DynamicColumn.CompareOperator.Eq:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) == column.Value)); break;
+ case DynamicColumn.CompareOperator.Not:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) != column.Value)); break;
+ case DynamicColumn.CompareOperator.Like:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).Like(column.Value))); break;
+ case DynamicColumn.CompareOperator.NotLike:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value)));
+ break;
+ case DynamicColumn.CompareOperator.In:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).In(column.Value))); break;
+ case DynamicColumn.CompareOperator.Lt:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) < column.Value)); break;
+ case DynamicColumn.CompareOperator.Lte:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) <= column.Value)); break;
+ case DynamicColumn.CompareOperator.Gt:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) > column.Value)); break;
+ case DynamicColumn.CompareOperator.Gte:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) >= column.Value)); break;
+ case DynamicColumn.CompareOperator.Between:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).Between(column.Value)));
+ break;
}
else
switch (column.Operator)
{
default:
- case DynamicColumn.CompareOperator.Eq: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) == column.Value); break;
- case DynamicColumn.CompareOperator.Not: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) != column.Value); break;
- case DynamicColumn.CompareOperator.Like: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).Like(column.Value)); break;
- case DynamicColumn.CompareOperator.NotLike: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value)); break;
- case DynamicColumn.CompareOperator.In: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).In(column.Value)); break;
- case DynamicColumn.CompareOperator.Lt: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) < column.Value); break;
- case DynamicColumn.CompareOperator.Lte: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) <= column.Value); break;
- case DynamicColumn.CompareOperator.Gt: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) > column.Value); break;
- case DynamicColumn.CompareOperator.Gte: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) >= column.Value); break;
- case DynamicColumn.CompareOperator.Between: builder.InternalHaving(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).Between(column.Value)); break;
+ case DynamicColumn.CompareOperator.Eq:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) == column.Value); break;
+ case DynamicColumn.CompareOperator.Not:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) != column.Value); break;
+ case DynamicColumn.CompareOperator.Like:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).Like(column.Value)); break;
+ case DynamicColumn.CompareOperator.NotLike:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value)); break;
+ case DynamicColumn.CompareOperator.In:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).In(column.Value)); break;
+ case DynamicColumn.CompareOperator.Lt:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) < column.Value); break;
+ case DynamicColumn.CompareOperator.Lte:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) <= column.Value); break;
+ case DynamicColumn.CompareOperator.Gt:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) > column.Value); break;
+ case DynamicColumn.CompareOperator.Gte:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) >= column.Value); break;
+ case DynamicColumn.CompareOperator.Between:
+ builder.InternalHaving(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).Between(column.Value)); break;
}
-
+
builder.OnCreateTemporaryParameter.Remove(modParam);
builder.VirtualMode = virt;
-
+
return builder;
}
-
- internal static T InternalHaving(this T builder, string column, DynamicColumn.CompareOperator op, object value) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
+
+ internal static T InternalHaving(this T builder, string column, DynamicColumn.CompareOperator op,
+ object value) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
{
if (value is DynamicColumn)
{
DynamicColumn v = (DynamicColumn)value;
-
+
if (string.IsNullOrEmpty(v.ColumnName))
v.ColumnName = column;
-
+
return builder.InternalHaving(v);
}
else if (value is IEnumerable)
{
foreach (DynamicColumn v in (IEnumerable)value)
builder.InternalHaving(v);
-
+
return builder;
}
-
+
return builder.InternalHaving(new DynamicColumn
{
ColumnName = column,
@@ -7849,13 +8100,15 @@ namespace DynamORM
Value = value
});
}
-
- internal static T InternalHaving(this T builder, string column, object value) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
+
+ internal static T InternalHaving(this T builder, string column, object value)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
{
return builder.InternalHaving(column, DynamicColumn.CompareOperator.Eq, value);
}
-
- internal static T InternalHaving(this T builder, object conditions, bool schema = false) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
+
+ internal static T InternalHaving(this T builder, object conditions, bool schema = false)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithHaving
{
if (conditions is DynamicColumn)
return builder.InternalHaving((DynamicColumn)conditions);
@@ -7863,58 +8116,62 @@ namespace DynamORM
{
foreach (DynamicColumn v in (IEnumerable)conditions)
builder.InternalHaving(v);
-
+
return builder;
}
-
+
IDictionary dict = conditions.ToDictionary();
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(conditions.GetType());
string table = dict.TryGetValue("_table").NullOr(x => x.ToString(), string.Empty);
-
+
foreach (KeyValuePair condition in dict)
{
if (mapper.Ignored.Contains(condition.Key) || condition.Key == "_table")
continue;
-
- string colName = mapper != null ? mapper.PropertyMap.TryGetValue(condition.Key) ?? condition.Key : condition.Key;
-
+
+ string colName = mapper != null
+ ? mapper.PropertyMap.TryGetValue(condition.Key) ?? condition.Key
+ : condition.Key;
+
DynamicSchemaColumn? col = null;
-
+
// This should be used on typed queries or update/delete steatements, which usualy operate on a single table.
if (schema)
{
col = builder.GetColumnFromSchema(colName, mapper, table);
-
+
if ((!col.HasValue || !col.Value.IsKey) &&
- (mapper == null || mapper.ColumnsMap.TryGetValue(colName).NullOr(m => m.Ignore || m.Column.NullOr(c => !c.IsKey, true), true)))
+ (mapper == null || mapper.ColumnsMap.TryGetValue(colName)
+ .NullOr(m => m.Ignore || m.Column.NullOr(c => !c.IsKey, true), true)))
continue;
-
+
colName = col.HasValue ? col.Value.Name : colName;
}
-
+
if (!string.IsNullOrEmpty(table))
- builder.InternalHaving(x => x(builder.FixObjectName(string.Format("{0}.{1}", table, colName))) == condition.Value);
+ builder.InternalHaving(x =>
+ x(builder.FixObjectName(string.Format("{0}.{1}", table, colName))) == condition.Value);
else
builder.InternalHaving(x => x(builder.FixObjectName(colName)) == condition.Value);
}
-
+
return builder;
}
-
+
#endregion Where
}
-
+
internal static class DynamicModifyBuilderExtensions
{
internal static T Table(this T builder, Func func) where T : DynamicModifyBuilder
{
if (func == null)
throw new ArgumentNullException("Function cannot be null.");
-
+
using (DynamicParser parser = DynamicParser.Parse(func))
{
object result = parser.Result;
-
+
// If the expression result is string.
if (result is string)
return builder.Table((string)result);
@@ -7924,95 +8181,110 @@ namespace DynamORM
{
// Or if it resolves to a dynamic node
DynamicParser.Node node = (DynamicParser.Node)result;
-
+
string owner = null;
string main = null;
-
+
while (true)
{
// Deny support for the AS() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
- throw new ArgumentException(string.Format("Alias is not supported on modification builders. (Parsing: {0})", result));
-
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
+ throw new ArgumentException(string.Format(
+ "Alias is not supported on modification builders. (Parsing: {0})", result));
+
// Support for table specifications...
if (node is DynamicParser.Node.GetMember)
{
if (owner != null)
- throw new ArgumentException(string.Format("Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
-
+ throw new ArgumentException(string.Format(
+ "Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
+
if (main != null)
owner = ((DynamicParser.Node.GetMember)node).Name;
else
main = ((DynamicParser.Node.GetMember)node).Name;
-
+
node = node.Host;
continue;
}
-
+
// Support for generic sources...
if (node is DynamicParser.Node.Invoke)
{
if (owner == null && main == null)
{
DynamicParser.Node.Invoke invoke = (DynamicParser.Node.Invoke)node;
-
+
if (invoke.Arguments.Length == 1 && invoke.Arguments[0] is Type)
return builder.Table((Type)invoke.Arguments[0]);
else if (invoke.Arguments.Length == 1 && invoke.Arguments[0] is String)
return builder.Table((string)invoke.Arguments[0]);
else
- throw new ArgumentException(string.Format("Invalid argument count or type when parsing '{2}'. Invoke supports only one argument of type Type or String", owner, main, result));
+ throw new ArgumentException(string.Format(
+ "Invalid argument count or type when parsing '{2}'. Invoke supports only one argument of type Type or String",
+ owner, main, result));
}
else if (owner != null)
- throw new ArgumentException(string.Format("Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
+ throw new ArgumentException(string.Format(
+ "Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
else if (main != null)
- throw new ArgumentException(string.Format("Main '{0}' is already set when parsing '{1}'.", main, result));
+ throw new ArgumentException(
+ string.Format("Main '{0}' is already set when parsing '{1}'.", main,
+ result));
}
-
+
if (!string.IsNullOrEmpty(main))
return builder.Table(string.Format("{0}{1}",
string.IsNullOrEmpty(owner) ? string.Empty : string.Format("{0}.", owner),
main));
}
}
-
+
throw new ArgumentException(string.Format("Unable to set table parsing '{0}'", result));
}
}
-
- internal static T Table(this T builder, string tableName, Dictionary schema = null) where T : DynamicModifyBuilder
+
+ internal static T Table(this T builder, string tableName,
+ Dictionary schema = null) where T : DynamicModifyBuilder
{
Tuple tuple = tableName.Validated("Table Name").SplitSomethingAndAlias();
-
+
if (!string.IsNullOrEmpty(tuple.Item2))
- throw new ArgumentException(string.Format("Can not use aliases in INSERT steatement. ({0})", tableName), "tableName");
-
+ throw new ArgumentException(
+ string.Format("Can not use aliases in INSERT steatement. ({0})", tableName), "tableName");
+
string[] parts = tuple.Item1.Split('.');
-
+
if (parts.Length > 2)
- throw new ArgumentException(string.Format("Table name can consist only from name or owner and name. ({0})", tableName), "tableName");
-
+ throw new ArgumentException(
+ string.Format("Table name can consist only from name or owner and name. ({0})", tableName),
+ "tableName");
+
builder.Tables.Clear();
builder.Tables.Add(new DynamicQueryBuilder.TableInfo(builder.Database,
- builder.Database.StripName(parts.Last()).Validated("Table"), null,
- parts.Length == 2 ? builder.Database.StripName(parts.First()).Validated("Owner", canbeNull: true) : null));
-
+ builder.Database.StripName(parts.Last()).Validated("Table"), null,
+ parts.Length == 2
+ ? builder.Database.StripName(parts.First()).Validated("Owner", canbeNull: true)
+ : null));
+
if (schema != null)
(builder.Tables[0] as DynamicQueryBuilder.TableInfo).Schema = schema;
-
+
return builder;
}
-
+
internal static T Table(this T builder, Type type) where T : DynamicQueryBuilder
{
if (type.IsAnonymous())
- throw new InvalidOperationException(string.Format("Cant assign anonymous type as a table ({0}).", type.FullName));
-
+ throw new InvalidOperationException(
+ string.Format("Cant assign anonymous type as a table ({0}).", type.FullName));
+
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
-
+
if (mapper == null)
throw new InvalidOperationException("Cant assign unmapable type as a table.");
-
+
if (builder is DynamicModifyBuilder)
{
builder.Tables.Clear();
@@ -8020,34 +8292,36 @@ namespace DynamORM
}
else if (builder is DynamicSelectQueryBuilder)
(builder as DynamicSelectQueryBuilder).From(x => x(type));
-
+
return builder;
}
}
-
+
internal static class DynamicWhereQueryExtensions
{
#region Where
-
- internal static T InternalWhere(this T builder, Func func) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+
+ internal static T InternalWhere(this T builder, Func func)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
{
return builder.InternalWhere(false, false, func);
}
-
- internal static T InternalWhere(this T builder, bool addBeginBrace, bool addEndBrace, Func func) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+
+ internal static T InternalWhere(this T builder, bool addBeginBrace, bool addEndBrace,
+ Func func) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
{
if (func == null) throw new ArgumentNullException("Array of functions cannot be null.");
-
+
using (DynamicParser parser = DynamicParser.Parse(func))
{
string condition = null;
bool and = true;
-
+
object result = parser.Result;
if (result is string)
{
condition = (string)result;
-
+
if (condition.ToUpper().IndexOf("OR") == 0)
{
and = false;
@@ -8061,113 +8335,163 @@ namespace DynamORM
else
{
// Intercepting the 'x => x.And()' and 'x => x.Or()' virtual methods...
- if (result is DynamicParser.Node.Method && ((DynamicParser.Node.Method)result).Host is DynamicParser.Node.Argument)
+ if (result is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)result).Host is DynamicParser.Node.Argument)
{
DynamicParser.Node.Method node = (DynamicParser.Node.Method)result;
string name = node.Name.ToUpper();
if (name == "AND" || name == "OR")
{
object[] args = ((DynamicParser.Node.Method)node).Arguments;
- if (args == null) throw new ArgumentNullException("arg", string.Format("{0} is not a parameterless method.", name));
- if (args.Length != 1) throw new ArgumentException(string.Format("{0} requires one and only one parameter: {1}.", name, args.Sketch()));
-
+ if (args == null)
+ throw new ArgumentNullException("arg",
+ string.Format("{0} is not a parameterless method.", name));
+ if (args.Length != 1)
+ throw new ArgumentException(string.Format(
+ "{0} requires one and only one parameter: {1}.", name, args.Sketch()));
+
and = name == "AND" ? true : false;
result = args[0];
}
}
-
+
// Just parsing the contents now...
condition = builder.Parse(result, pars: builder.Parameters).Validated("Where condition");
}
-
+
if (addBeginBrace) builder.WhereOpenBracketsCount++;
if (addEndBrace) builder.WhereOpenBracketsCount--;
-
+
if (builder.WhereCondition == null)
builder.WhereCondition = string.Format("{0}{1}{2}",
addBeginBrace ? "(" : string.Empty, condition, addEndBrace ? ")" : string.Empty);
else
- builder.WhereCondition = string.Format("{0} {1} {2}{3}{4}", builder.WhereCondition, and ? "AND" : "OR",
+ builder.WhereCondition = string.Format("{0} {1} {2}{3}{4}", builder.WhereCondition,
+ and ? "AND" : "OR",
addBeginBrace ? "(" : string.Empty, condition, addEndBrace ? ")" : string.Empty);
}
-
+
return builder;
}
-
- internal static T InternalWhere(this T builder, DynamicColumn column) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+
+ internal static T InternalWhere(this T builder, DynamicColumn column)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
{
bool virt = builder.VirtualMode;
if (column.VirtualColumn.HasValue)
builder.VirtualMode = column.VirtualColumn.Value;
-
+
Action modParam = (p) =>
{
if (column.Schema.HasValue)
p.Schema = column.Schema;
-
+
if (!p.Schema.HasValue)
p.Schema = column.Schema ?? builder.GetColumnFromSchema(column.ColumnName);
};
-
+
builder.CreateTemporaryParameterAction(modParam);
-
+
// It's kind of uglu, but... well it works.
if (column.Or)
switch (column.Operator)
{
default:
- case DynamicColumn.CompareOperator.Eq: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) == column.Value)); break;
- case DynamicColumn.CompareOperator.Not: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) != column.Value)); break;
- case DynamicColumn.CompareOperator.Like: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).Like(column.Value))); break;
- case DynamicColumn.CompareOperator.NotLike: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value))); break;
- case DynamicColumn.CompareOperator.In: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).In(column.Value))); break;
- case DynamicColumn.CompareOperator.Lt: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) < column.Value)); break;
- case DynamicColumn.CompareOperator.Lte: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) <= column.Value)); break;
- case DynamicColumn.CompareOperator.Gt: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) > column.Value)); break;
- case DynamicColumn.CompareOperator.Gte: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)) >= column.Value)); break;
- case DynamicColumn.CompareOperator.Between: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x.Or(x(builder.FixObjectName(column.ColumnName)).Between(column.Value))); break;
+ case DynamicColumn.CompareOperator.Eq:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) == column.Value)); break;
+ case DynamicColumn.CompareOperator.Not:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) != column.Value)); break;
+ case DynamicColumn.CompareOperator.Like:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).Like(column.Value))); break;
+ case DynamicColumn.CompareOperator.NotLike:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value)));
+ break;
+ case DynamicColumn.CompareOperator.In:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).In(column.Value))); break;
+ case DynamicColumn.CompareOperator.Lt:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) < column.Value)); break;
+ case DynamicColumn.CompareOperator.Lte:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) <= column.Value)); break;
+ case DynamicColumn.CompareOperator.Gt:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) > column.Value)); break;
+ case DynamicColumn.CompareOperator.Gte:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)) >= column.Value)); break;
+ case DynamicColumn.CompareOperator.Between:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x.Or(x(builder.FixObjectName(column.ColumnName)).Between(column.Value)));
+ break;
}
else
switch (column.Operator)
{
default:
- case DynamicColumn.CompareOperator.Eq: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) == column.Value); break;
- case DynamicColumn.CompareOperator.Not: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) != column.Value); break;
- case DynamicColumn.CompareOperator.Like: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).Like(column.Value)); break;
- case DynamicColumn.CompareOperator.NotLike: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value)); break;
- case DynamicColumn.CompareOperator.In: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).In(column.Value)); break;
- case DynamicColumn.CompareOperator.Lt: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) < column.Value); break;
- case DynamicColumn.CompareOperator.Lte: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) <= column.Value); break;
- case DynamicColumn.CompareOperator.Gt: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) > column.Value); break;
- case DynamicColumn.CompareOperator.Gte: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)) >= column.Value); break;
- case DynamicColumn.CompareOperator.Between: builder.InternalWhere(column.BeginBlock, column.EndBlock, x => x(builder.FixObjectName(column.ColumnName)).Between(column.Value)); break;
+ case DynamicColumn.CompareOperator.Eq:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) == column.Value); break;
+ case DynamicColumn.CompareOperator.Not:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) != column.Value); break;
+ case DynamicColumn.CompareOperator.Like:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).Like(column.Value)); break;
+ case DynamicColumn.CompareOperator.NotLike:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).NotLike(column.Value)); break;
+ case DynamicColumn.CompareOperator.In:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).In(column.Value)); break;
+ case DynamicColumn.CompareOperator.Lt:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) < column.Value); break;
+ case DynamicColumn.CompareOperator.Lte:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) <= column.Value); break;
+ case DynamicColumn.CompareOperator.Gt:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) > column.Value); break;
+ case DynamicColumn.CompareOperator.Gte:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)) >= column.Value); break;
+ case DynamicColumn.CompareOperator.Between:
+ builder.InternalWhere(column.BeginBlock, column.EndBlock,
+ x => x(builder.FixObjectName(column.ColumnName)).Between(column.Value)); break;
}
-
+
builder.OnCreateTemporaryParameter.Remove(modParam);
builder.VirtualMode = virt;
-
+
return builder;
}
-
- internal static T InternalWhere(this T builder, string column, DynamicColumn.CompareOperator op, object value) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+
+ internal static T InternalWhere(this T builder, string column, DynamicColumn.CompareOperator op,
+ object value) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
{
if (value is DynamicColumn)
{
DynamicColumn v = (DynamicColumn)value;
-
+
if (string.IsNullOrEmpty(v.ColumnName))
v.ColumnName = column;
-
+
return builder.InternalWhere(v);
}
else if (value is IEnumerable)
{
foreach (DynamicColumn v in (IEnumerable)value)
builder.InternalWhere(v);
-
+
return builder;
}
-
+
return builder.InternalWhere(new DynamicColumn
{
ColumnName = column,
@@ -8175,13 +8499,15 @@ namespace DynamORM
Value = value
});
}
-
- internal static T InternalWhere(this T builder, string column, object value) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+
+ internal static T InternalWhere(this T builder, string column, object value)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
{
return builder.InternalWhere(column, DynamicColumn.CompareOperator.Eq, value);
}
-
- internal static T InternalWhere(this T builder, object conditions, bool schema = false) where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+
+ internal static T InternalWhere(this T builder, object conditions, bool schema = false)
+ where T : DynamicQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
{
if (conditions is DynamicColumn)
return builder.InternalWhere((DynamicColumn)conditions);
@@ -8189,52 +8515,57 @@ namespace DynamORM
{
foreach (DynamicColumn v in (IEnumerable)conditions)
builder.InternalWhere(v);
-
+
return builder;
}
-
+
IDictionary dict = conditions.ToDictionary();
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(conditions.GetType());
string table = dict.TryGetValue("_table").NullOr(x => x.ToString(), string.Empty);
-
+
foreach (KeyValuePair condition in dict)
{
if (mapper.Ignored.Contains(condition.Key) || condition.Key == "_table")
continue;
-
- string colName = mapper != null ? mapper.PropertyMap.TryGetValue(condition.Key) ?? condition.Key : condition.Key;
-
+
+ string colName = mapper != null
+ ? mapper.PropertyMap.TryGetValue(condition.Key) ?? condition.Key
+ : condition.Key;
+
DynamicSchemaColumn? col = null;
-
+
// This should be used on typed queries or update/delete steatements, which usualy operate on a single table.
if (schema)
{
col = builder.GetColumnFromSchema(colName, mapper, table);
-
+
if ((!col.HasValue || !col.Value.IsKey) &&
- (mapper == null || mapper.ColumnsMap.TryGetValue(colName).NullOr(m => m.Ignore || m.Column.NullOr(c => !c.IsKey, true), true)))
+ (mapper == null || mapper.ColumnsMap.TryGetValue(colName)
+ .NullOr(m => m.Ignore || m.Column.NullOr(c => !c.IsKey, true), true)))
continue;
-
+
colName = col.HasValue ? col.Value.Name : colName;
}
-
+
if (!string.IsNullOrEmpty(table))
- builder.InternalWhere(x => x(builder.FixObjectName(string.Format("{0}.{1}", table, colName))) == condition.Value);
+ builder.InternalWhere(x =>
+ x(builder.FixObjectName(string.Format("{0}.{1}", table, colName))) == condition.Value);
else
builder.InternalWhere(x => x(builder.FixObjectName(colName)) == condition.Value);
}
-
+
return builder;
}
-
+
#endregion Where
}
}
namespace Implementation
- {
+ {
/// Implementation of dynamic delete query builder.
- internal class DynamicDeleteQueryBuilder : DynamicModifyBuilder, IDynamicDeleteQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+ internal class DynamicDeleteQueryBuilder : DynamicModifyBuilder, IDynamicDeleteQueryBuilder,
+ DynamicQueryBuilder.IQueryWithWhere
{
///
/// Initializes a new instance of the class.
@@ -8244,7 +8575,7 @@ namespace DynamORM
: base(db)
{
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -8254,7 +8585,7 @@ namespace DynamORM
: base(db, tableName)
{
}
-
+
/// Generates the text this command will execute against the underlying database.
/// The text to execute against the underlying database.
/// This method must be override by derived classes.
@@ -8262,14 +8593,16 @@ namespace DynamORM
{
ITableInfo info = Tables.Single();
return string.Format("DELETE FROM {0}{1}{2}{3}",
- string.IsNullOrEmpty(info.Owner) ? string.Empty : string.Format("{0}.", Database.DecorateName(info.Owner)),
+ string.IsNullOrEmpty(info.Owner)
+ ? string.Empty
+ : string.Format("{0}.", Database.DecorateName(info.Owner)),
Database.DecorateName(info.Name),
string.IsNullOrEmpty(WhereCondition) ? string.Empty : " WHERE ",
WhereCondition);
}
-
+
#region Where
-
+
///
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
@@ -8284,7 +8617,7 @@ namespace DynamORM
{
return this.InternalWhere(func);
}
-
+
/// Add where condition.
/// Condition column with operator and value.
/// Builder instance.
@@ -8292,17 +8625,18 @@ namespace DynamORM
{
return this.InternalWhere(column);
}
-
+
/// Add where condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
- public virtual IDynamicDeleteQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value)
+ public virtual IDynamicDeleteQueryBuilder Where(string column, DynamicColumn.CompareOperator op,
+ object value)
{
return this.InternalWhere(column, op, value);
}
-
+
/// Add where condition.
/// Condition column.
/// Condition value.
@@ -8311,7 +8645,7 @@ namespace DynamORM
{
return this.InternalWhere(column, value);
}
-
+
/// Add where condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
@@ -8321,16 +8655,16 @@ namespace DynamORM
{
return this.InternalWhere(conditions, schema);
}
-
+
#endregion Where
}
-
+
/// Implementation of dynamic insert query builder.
internal class DynamicInsertQueryBuilder : DynamicModifyBuilder, IDynamicInsertQueryBuilder
{
private string _columns;
private string _values;
-
+
///
/// Initializes a new instance of the class.
///
@@ -8339,7 +8673,7 @@ namespace DynamORM
: base(db)
{
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -8349,7 +8683,7 @@ namespace DynamORM
: base(db, tableName)
{
}
-
+
/// Generates the text this command will execute against the underlying database.
/// The text to execute against the underlying database.
/// This method must be override by derived classes.
@@ -8357,12 +8691,14 @@ namespace DynamORM
{
ITableInfo info = Tables.Single();
return string.Format("INSERT INTO {0}{1} ({2}) VALUES ({3})",
- string.IsNullOrEmpty(info.Owner) ? string.Empty : string.Format("{0}.", Database.DecorateName(info.Owner)),
+ string.IsNullOrEmpty(info.Owner)
+ ? string.Empty
+ : string.Format("{0}.", Database.DecorateName(info.Owner)),
Database.DecorateName(info.Name), _columns, _values);
}
-
+
#region Insert
-
+
///
/// Specifies the columns to insert using the dynamic lambda expressions given. Each expression correspond to one
/// column, and can:
@@ -8372,46 +8708,47 @@ namespace DynamORM
/// The specifications.
/// The specifications.
/// This instance to permit chaining.
- public virtual IDynamicInsertQueryBuilder Values(Func fn, params Func[] func)
+ public virtual IDynamicInsertQueryBuilder Values(Func fn,
+ params Func[] func)
{
if (fn == null)
throw new ArgumentNullException("Array of specifications cannot be null.");
-
+
int index = InsertFunc(-1, fn);
-
+
if (func != null)
foreach (Func f in func)
index = InsertFunc(index, f);
-
+
return this;
}
-
+
private int InsertFunc(int index, Func f)
{
index++;
-
+
if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
-
+
using (DynamicParser parser = DynamicParser.Parse(f))
{
object result = parser.Result;
if (result == null)
throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
-
+
string main = null;
string value = null;
string str = null;
-
+
// When 'x => x.Table.Column = value' or 'x => x.Column = value'...
if (result is DynamicParser.Node.SetMember)
{
DynamicParser.Node.SetMember node = (DynamicParser.Node.SetMember)result;
-
+
DynamicSchemaColumn? col = GetColumnFromSchema(node.Name);
main = Database.DecorateName(node.Name);
value = Parse(node.Value, ref col, pars: Parameters, nulls: true);
-
+
_columns = _columns == null ? main : string.Format("{0}, {1}", _columns, main);
_values = _values == null ? value : string.Format("{0}, {1}", _values, value);
return index;
@@ -8421,7 +8758,7 @@ namespace DynamORM
Insert(result);
return index;
}
-
+
// Other specifications are considered invalid...
string err = string.Format("Specification '{0}' is invalid.", result);
str = Parse(result);
@@ -8429,7 +8766,7 @@ namespace DynamORM
throw new ArgumentException(err);
}
}
-
+
/// Add insert fields.
/// Insert column.
/// Insert value.
@@ -8439,20 +8776,20 @@ namespace DynamORM
if (value is DynamicColumn)
{
DynamicColumn v = (DynamicColumn)value;
-
+
if (string.IsNullOrEmpty(v.ColumnName))
v.ColumnName = column;
-
+
return Insert(v);
}
-
+
return Insert(new DynamicColumn
{
ColumnName = column,
Value = value,
});
}
-
+
/// Add insert fields.
/// Set insert value as properties and values of an object.
/// Builder instance.
@@ -8462,19 +8799,19 @@ namespace DynamORM
{
DynamicColumn column = (DynamicColumn)o;
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
-
+
string main = FixObjectName(column.ColumnName, onlyColumn: true);
string value = Parse(column.Value, ref col, pars: Parameters, nulls: true);
-
+
_columns = _columns == null ? main : string.Format("{0}, {1}", _columns, main);
_values = _values == null ? value : string.Format("{0}, {1}", _values, value);
-
+
return this;
}
-
+
IDictionary dict = o.ToDictionary();
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(o.GetType());
-
+
if (mapper != null)
{
foreach (KeyValuePair con in dict)
@@ -8482,7 +8819,7 @@ namespace DynamORM
{
string colName = mapper.PropertyMap.TryGetValue(con.Key) ?? con.Key;
DynamicPropertyInvoker propMap = mapper.ColumnsMap.TryGetValue(colName.ToLower());
-
+
if (propMap == null || propMap.Column == null || !propMap.Column.IsNoInsert)
Insert(colName, con.Value); // TODO: This probably should get value from mapper
}
@@ -8490,26 +8827,26 @@ namespace DynamORM
else
foreach (KeyValuePair con in dict)
Insert(con.Key, con.Value);
-
+
return this;
}
-
+
#endregion Insert
-
+
#region IExtendedDisposable
-
+
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
public override void Dispose()
{
base.Dispose();
-
+
_columns = _values = null;
}
-
+
#endregion IExtendedDisposable
}
-
+
/// Base query builder for insert/update/delete statements.
internal abstract class DynamicModifyBuilder : DynamicQueryBuilder
{
@@ -8522,7 +8859,7 @@ namespace DynamORM
{
VirtualMode = false;
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -8534,7 +8871,7 @@ namespace DynamORM
VirtualMode = false;
this.Table(tableName);
}
-
+
/// Execute this builder.
/// Result of an execution..
public virtual int Execute()
@@ -8548,7 +8885,7 @@ namespace DynamORM
}
}
}
-
+
/// Implementation of dynamic query builder base interface.
internal abstract class DynamicQueryBuilder : IDynamicQueryBuilder
{
@@ -8557,25 +8894,25 @@ namespace DynamORM
{
/// Gets or sets the where condition.
string WhereCondition { get; set; }
-
+
/// Gets or sets the amount of not closed brackets in where statement.
int WhereOpenBracketsCount { get; set; }
}
-
+
/// Empty interface to allow having query builder implementation use universal approach.
internal interface IQueryWithHaving
{
/// Gets or sets the having condition.
string HavingCondition { get; set; }
-
+
/// Gets or sets the amount of not closed brackets in having statement.
int HavingOpenBracketsCount { get; set; }
}
-
+
private DynamicQueryBuilder _parent = null;
-
+
#region TableInfo
-
+
/// Table information.
internal class TableInfo : ITableInfo
{
@@ -8586,7 +8923,7 @@ namespace DynamORM
{
IsDisposed = false;
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -8595,18 +8932,19 @@ namespace DynamORM
/// The table alias.
/// The table owner.
/// The table should be used with nolock.
- public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null, bool nolock = false)
+ public TableInfo(DynamicDatabase db, string name, string alias = null, string owner = null,
+ bool nolock = false)
: this()
{
Name = name;
Alias = alias;
Owner = owner;
NoLock = nolock;
-
+
if (!name.ContainsAny(StringExtensions.InvalidMemberChars))
Schema = db.GetSchema(name, owner: owner);
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -8615,53 +8953,55 @@ namespace DynamORM
/// The table alias.
/// The table owner.
/// The table should be used with nolock.
- public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null, bool nolock = false)
+ public TableInfo(DynamicDatabase db, Type type, string alias = null, string owner = null,
+ bool nolock = false)
: this()
{
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
-
- Name = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
- mapper.Type.Name : mapper.Table.Name;
-
+
+ Name = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name)
+ ? mapper.Type.Name
+ : mapper.Table.Name;
+
Owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
Alias = alias;
NoLock = nolock;
-
+
Schema = db.GetSchema(type);
}
-
+
/// Gets or sets table owner name.
public string Owner { get; internal set; }
-
+
/// Gets or sets table name.
public string Name { get; internal set; }
-
+
/// Gets or sets table alias.
public string Alias { get; internal set; }
-
+
/// Gets or sets table alias.
public bool NoLock { get; internal set; }
-
+
/// Gets or sets table schema.
public Dictionary Schema { get; internal set; }
-
+
/// Gets a value indicating whether this instance is disposed.
public bool IsDisposed { get; private set; }
-
+
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
public virtual void Dispose()
{
IsDisposed = true;
-
+
////if (Schema != null)
//// Schema.Clear();
-
+
Owner = Name = Alias = null;
Schema = null;
}
}
-
+
/// Generic based table information.
/// Type of class that is represented in database.
internal class TableInfo : TableInfo
@@ -8677,11 +9017,11 @@ namespace DynamORM
{
}
}
-
+
#endregion TableInfo
-
+
#region Parameter
-
+
/// Interface describing parameter info.
internal class Parameter : IParameter
{
@@ -8691,44 +9031,44 @@ namespace DynamORM
{
IsDisposed = false;
}
-
+
/// Gets or sets the parameter position in command.
/// Available after filling the command.
public int Ordinal { get; internal set; }
-
+
/// Gets or sets the parameter temporary name.
public string Name { get; internal set; }
-
+
/// Gets or sets the parameter value.
public object Value { get; set; }
-
+
/// Gets or sets a value indicating whether name of temporary parameter is well known.
public bool WellKnown { get; set; }
-
+
/// Gets or sets a value indicating whether this is virtual.
public bool Virtual { get; set; }
-
+
/// Gets or sets the parameter schema information.
public DynamicSchemaColumn? Schema { get; set; }
-
+
/// Gets a value indicating whether this instance is disposed.
public bool IsDisposed { get; private set; }
-
+
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
public virtual void Dispose()
{
IsDisposed = true;
-
+
Name = null;
Schema = null;
}
}
-
+
#endregion Parameter
-
+
#region Constructor
-
+
///
/// Initializes a new instance of the class.
///
@@ -8741,18 +9081,20 @@ namespace DynamORM
Parameters = new Dictionary();
OnCreateTemporaryParameter = new List>();
OnCreateParameter = new List>();
-
+
WhereCondition = null;
WhereOpenBracketsCount = 0;
-
+
Database = db;
if (Database != null)
Database.AddToCache(this);
-
- SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) == DynamicDatabaseOptions.SupportSchema;
- SupportNoLock = (db.Options & DynamicDatabaseOptions.SupportNoLock) == DynamicDatabaseOptions.SupportNoLock;
+
+ SupportSchema = (db.Options & DynamicDatabaseOptions.SupportSchema) ==
+ DynamicDatabaseOptions.SupportSchema;
+ SupportNoLock = (db.Options & DynamicDatabaseOptions.SupportNoLock) ==
+ DynamicDatabaseOptions.SupportNoLock;
}
-
+
/// Initializes a new instance of the class.
/// The database.
/// The parent query.
@@ -8761,54 +9103,54 @@ namespace DynamORM
{
_parent = parent;
}
-
+
#endregion Constructor
-
+
#region IQueryWithWhere
-
+
/// Gets or sets the where condition.
public string WhereCondition { get; set; }
-
+
/// Gets or sets the amount of not closed brackets in where statement.
public int WhereOpenBracketsCount { get; set; }
-
+
#endregion IQueryWithWhere
-
+
#region IDynamicQueryBuilder
-
+
/// Gets instance.
public DynamicDatabase Database { get; private set; }
-
+
/// Gets the tables used in this builder.
public IList Tables { get; private set; }
-
+
/// Gets the tables used in this builder.
public IDictionary Parameters { get; private set; }
-
+
/// Gets or sets a value indicating whether add virtual parameters.
public bool VirtualMode { get; set; }
-
+
/// Gets or sets the on create temporary parameter actions.
/// This is exposed to allow setting schema of column.
public List> OnCreateTemporaryParameter { get; set; }
-
+
/// Gets or sets the on create real parameter actions.
/// This is exposed to allow modification of parameter.
public List> OnCreateParameter { get; set; }
-
+
/// Gets a value indicating whether database supports standard schema.
public bool SupportSchema { get; private set; }
-
+
/// Gets a value indicating whether database supports with no lock syntax.
public bool SupportNoLock { get; private set; }
-
+
///
/// Generates the text this command will execute against the underlying database.
///
/// The text to execute against the underlying database.
/// This method must be override by derived classes.
public abstract string CommandText();
-
+
/// Fill command with query.
/// Command to fill.
/// Filled instance of .
@@ -8823,19 +9165,19 @@ namespace DynamORM
WhereOpenBracketsCount--;
}
}
-
+
// End not ended having statement
if (this is IQueryWithHaving)
{
IQueryWithHaving h = this as IQueryWithHaving;
-
+
while (h.HavingOpenBracketsCount > 0)
{
h.HavingCondition += ")";
h.HavingOpenBracketsCount--;
}
}
-
+
return command.SetCommand(CommandText()
.FillStringWithVariables(s =>
{
@@ -8844,21 +9186,21 @@ namespace DynamORM
IDbDataParameter param = (IDbDataParameter)command
.AddParameter(this, p.Schema, p.Value)
.Parameters[command.Parameters.Count - 1];
-
+
(p as Parameter).Ordinal = command.Parameters.Count - 1;
-
+
if (OnCreateParameter != null)
OnCreateParameter.ForEach(x => x(p, param));
-
+
return param.ParameterName;
}, s);
}));
}
-
+
#endregion IDynamicQueryBuilder
-
+
#region Parser
-
+
/// Parses the arbitrary object given and translates it into a string with the appropriate
/// syntax for the database this parser is specific to.
/// The object to parse and translate. It can be any arbitrary object, including null values (if
@@ -8873,13 +9215,14 @@ namespace DynamORM
/// A string containing the result of the parsing, along with the parameters extracted in the
/// instance if such is given.
/// Null nodes are not accepted.
- internal virtual string Parse(object node, IDictionary pars = null, bool rawstr = false, bool nulls = false, bool decorate = true, bool isMultiPart = true)
+ internal virtual string Parse(object node, IDictionary pars = null,
+ bool rawstr = false, bool nulls = false, bool decorate = true, bool isMultiPart = true)
{
DynamicSchemaColumn? c = null;
-
+
return Parse(node, ref c, pars, rawstr, nulls, decorate, isMultiPart);
}
-
+
/// Parses the arbitrary object given and translates it into a string with the appropriate
/// syntax for the database this parser is specific to.
/// The object to parse and translate. It can be any arbitrary object, including null values (if
@@ -8895,92 +9238,110 @@ namespace DynamORM
/// A string containing the result of the parsing, along with the parameters extracted in the
/// instance if such is given.
/// Null nodes are not accepted.
- internal virtual string Parse(object node, ref DynamicSchemaColumn? columnSchema, IDictionary pars = null, bool rawstr = false, bool nulls = false, bool decorate = true, bool isMultiPart = true)
+ internal virtual string Parse(object node, ref DynamicSchemaColumn? columnSchema,
+ IDictionary pars = null, bool rawstr = false, bool nulls = false,
+ bool decorate = true, bool isMultiPart = true)
{
// Null nodes are accepted or not depending upon the "nulls" flag...
if (node == null)
{
if (!nulls)
throw new ArgumentNullException("node", "Null nodes are not accepted.");
-
+
return Dispatch(node, ref columnSchema, pars, decorate);
}
-
+
// Nodes that are strings are parametrized or not depending the "rawstr" flag...
if (node is string)
{
if (rawstr) return (string)node;
else return Dispatch(node, ref columnSchema, pars, decorate);
}
-
+
// If node is a delegate, parse it to create the logical tree...
if (node is Delegate)
{
using (DynamicParser p = DynamicParser.Parse((Delegate)node))
{
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);
}
-
- private string Dispatch(object node, ref DynamicSchemaColumn? columnSchema, IDictionary pars = null, bool decorate = true, bool isMultiPart = true)
+
+ private string Dispatch(object node, ref DynamicSchemaColumn? columnSchema,
+ IDictionary pars = null, bool decorate = true, bool isMultiPart = true)
{
if (node != null)
{
if (node is DynamicQueryBuilder) return ParseCommand((DynamicQueryBuilder)node, pars);
- else if (node is DynamicParser.Node.Argument) return ParseArgument((DynamicParser.Node.Argument)node, isMultiPart);
- else if (node is DynamicParser.Node.GetMember) return ParseGetMember((DynamicParser.Node.GetMember)node, ref columnSchema, pars, decorate, isMultiPart);
- else if (node is DynamicParser.Node.SetMember) return ParseSetMember((DynamicParser.Node.SetMember)node, ref columnSchema, pars, decorate, isMultiPart);
- else if (node is DynamicParser.Node.Unary) return ParseUnary((DynamicParser.Node.Unary)node, pars);
- else if (node is DynamicParser.Node.Binary) return ParseBinary((DynamicParser.Node.Binary)node, pars);
- else if (node is DynamicParser.Node.Method) return ParseMethod((DynamicParser.Node.Method)node, ref columnSchema, pars);
- else if (node is DynamicParser.Node.Invoke) return ParseInvoke((DynamicParser.Node.Invoke)node, ref columnSchema, pars);
- else if (node is DynamicParser.Node.Convert) return ParseConvert((DynamicParser.Node.Convert)node, pars);
+ else if (node is DynamicParser.Node.Argument)
+ return ParseArgument((DynamicParser.Node.Argument)node, isMultiPart);
+ else if (node is DynamicParser.Node.GetMember)
+ return ParseGetMember((DynamicParser.Node.GetMember)node, ref columnSchema, pars, decorate,
+ isMultiPart);
+ else if (node is DynamicParser.Node.SetMember)
+ return ParseSetMember((DynamicParser.Node.SetMember)node, ref columnSchema, pars, decorate,
+ isMultiPart);
+ else if (node is DynamicParser.Node.Unary)
+ return ParseUnary((DynamicParser.Node.Unary)node, pars);
+ else if (node is DynamicParser.Node.Binary)
+ return ParseBinary((DynamicParser.Node.Binary)node, pars);
+ else if (node is DynamicParser.Node.Method)
+ return ParseMethod((DynamicParser.Node.Method)node, ref columnSchema, pars);
+ else if (node is DynamicParser.Node.Invoke)
+ return ParseInvoke((DynamicParser.Node.Invoke)node, ref columnSchema, pars);
+ else if (node is DynamicParser.Node.Convert)
+ return ParseConvert((DynamicParser.Node.Convert)node, pars);
}
-
+
// All other cases are considered constant parameters...
return ParseConstant(node, pars, columnSchema);
}
-
- internal virtual string ParseCommand(DynamicQueryBuilder node, IDictionary pars = null)
+
+ internal virtual string ParseCommand(DynamicQueryBuilder node,
+ IDictionary pars = null)
{
// Getting the command's text...
string str = node.CommandText(); // Avoiding spurious "OUTPUT XXX" statements
-
+
// If there are parameters to transform, but cannot store them, it is an error
if (node.Parameters.Count != 0 && pars == null)
return string.Format("({0})", str);
-
+
// TODO: Make special condiion
////throw new InvalidOperationException(string.Format("The parameters in this command '{0}' cannot be added to a null collection.", node.Parameters));
-
+
// Copy parameters to new comand
foreach (KeyValuePair parameter in node.Parameters)
pars.Add(parameter.Key, parameter.Value);
-
+
return string.Format("({0})", str);
}
-
- protected virtual string ParseArgument(DynamicParser.Node.Argument node, bool isMultiPart = true, bool isOwner = false)
+
+ protected virtual string ParseArgument(DynamicParser.Node.Argument node, bool isMultiPart = true,
+ bool isOwner = false)
{
if (!string.IsNullOrEmpty(node.Name) && (isOwner || (isMultiPart && IsTableAlias(node.Name))))
return node.Name;
-
+
return null;
}
-
- protected virtual string ParseGetMember(DynamicParser.Node.GetMember node, ref DynamicSchemaColumn? columnSchema, IDictionary pars = null, bool decorate = true, bool isMultiPart = true)
+
+ protected virtual string ParseGetMember(DynamicParser.Node.GetMember node,
+ ref DynamicSchemaColumn? columnSchema, IDictionary pars = null,
+ bool decorate = true, bool isMultiPart = true)
{
if (node.Host is DynamicParser.Node.Argument && IsTableAlias(node.Name))
{
decorate = false;
isMultiPart = false;
}
-
+
// This hack allows to use argument as alias, but when it is not nesesary use other column.
// Let say we hace a table Users with alias usr, and we join to table with alias ua which also has a column Users
// This allow use of usr => usr.ua.Users to result in ua."Users" instead of "Users" or usr."ua"."Users", se tests for examples.
@@ -8989,78 +9350,86 @@ namespace DynamORM
{
if (isMultiPart && node.Host is DynamicParser.Node.GetMember && IsTable(node.Host.Name, null))
{
- if (node.Host.Host != null && node.Host.Host is DynamicParser.Node.GetMember && IsTable(node.Host.Name, node.Host.Host.Name))
- parent = string.Format("{0}.{1}", Parse(node.Host.Host, pars, isMultiPart: false), Parse(node.Host, pars, isMultiPart: false));
+ if (node.Host.Host != null && node.Host.Host is DynamicParser.Node.GetMember &&
+ IsTable(node.Host.Name, node.Host.Host.Name))
+ parent = string.Format("{0}.{1}", Parse(node.Host.Host, pars, isMultiPart: false),
+ Parse(node.Host, pars, isMultiPart: false));
else
parent = Parse(node.Host, pars, isMultiPart: false);
}
else if (isMultiPart)
parent = Parse(node.Host, pars, isMultiPart: isMultiPart);
}
-
+
////string parent = node.Host == null || !isMultiPart ? null : Parse(node.Host, pars, isMultiPart: !IsTable(node.Name, node.Host.Name));
- string name = parent == null ?
- decorate ? Database.DecorateName(node.Name) : node.Name :
- string.Format("{0}.{1}", parent, decorate ? Database.DecorateName(node.Name) : node.Name);
-
+ string name = parent == null
+ ? decorate ? Database.DecorateName(node.Name) : node.Name
+ : string.Format("{0}.{1}", parent, decorate ? Database.DecorateName(node.Name) : node.Name);
+
columnSchema = GetColumnFromSchema(name);
-
+
return name;
}
-
- protected virtual string ParseSetMember(DynamicParser.Node.SetMember node, ref DynamicSchemaColumn? columnSchema, IDictionary pars = null, bool decorate = true, bool isMultiPart = true)
+
+ protected virtual string ParseSetMember(DynamicParser.Node.SetMember node,
+ ref DynamicSchemaColumn? columnSchema, IDictionary pars = null,
+ bool decorate = true, bool isMultiPart = true)
{
if (node.Host is DynamicParser.Node.Argument && IsTableAlias(node.Name))
{
decorate = false;
isMultiPart = false;
}
-
+
string parent = null;
if (node.Host != null)
{
if (isMultiPart && node.Host is DynamicParser.Node.GetMember && IsTable(node.Host.Name, null))
{
- if (node.Host.Host != null && node.Host.Host is DynamicParser.Node.GetMember && IsTable(node.Name, node.Host.Name))
- parent = string.Format("{0}.{1}", Parse(node.Host.Host, pars, isMultiPart: false), Parse(node.Host, pars, isMultiPart: false));
+ if (node.Host.Host != null && node.Host.Host is DynamicParser.Node.GetMember &&
+ IsTable(node.Name, node.Host.Name))
+ parent = string.Format("{0}.{1}", Parse(node.Host.Host, pars, isMultiPart: false),
+ Parse(node.Host, pars, isMultiPart: false));
else
parent = Parse(node.Host, pars, isMultiPart: false);
}
else if (isMultiPart)
parent = Parse(node.Host, pars, isMultiPart: isMultiPart);
}
-
+
////string parent = node.Host == null || !isMultiPart ? null : Parse(node.Host, pars, isMultiPart: !IsTable(node.Name, node.Host.Name));
- string name = parent == null ?
- decorate ? Database.DecorateName(node.Name) : node.Name :
- string.Format("{0}.{1}", parent, decorate ? Database.DecorateName(node.Name) : node.Name);
-
+ string name = parent == null
+ ? decorate ? Database.DecorateName(node.Name) : node.Name
+ : string.Format("{0}.{1}", parent, decorate ? Database.DecorateName(node.Name) : node.Name);
+
columnSchema = GetColumnFromSchema(name);
-
+
string value = Parse(node.Value, ref columnSchema, pars, nulls: true);
return string.Format("{0} = ({1})", name, value);
}
-
- protected virtual string ParseUnary(DynamicParser.Node.Unary node, IDictionary pars = null)
+
+ protected virtual string ParseUnary(DynamicParser.Node.Unary node,
+ IDictionary pars = null)
{
switch (node.Operation)
{
// Artifacts from the DynamicParser class that are not usefull here...
case ExpressionType.IsFalse:
case ExpressionType.IsTrue: return Parse(node.Target, pars);
-
+
// Unary supported operations...
case ExpressionType.Not: return string.Format("(NOT {0})", Parse(node.Target, pars));
case ExpressionType.Negate: return string.Format("!({0})", Parse(node.Target, pars));
}
-
+
throw new ArgumentException("Not supported unary operation: " + node);
}
-
- protected virtual string ParseBinary(DynamicParser.Node.Binary node, IDictionary pars = null)
+
+ protected virtual string ParseBinary(DynamicParser.Node.Binary node,
+ IDictionary pars = null)
{
string op = string.Empty;
-
+
switch (node.Operation)
{
// Arithmetic binary operations...
@@ -9070,467 +9439,509 @@ namespace DynamORM
case ExpressionType.Divide: op = "/"; break;
case ExpressionType.Modulo: op = "%"; break;
case ExpressionType.Power: op = "^"; break;
-
+
case ExpressionType.And: op = "AND"; break;
case ExpressionType.Or: op = "OR"; break;
-
+
// Logical comparisons...
case ExpressionType.GreaterThan: op = ">"; break;
case ExpressionType.GreaterThanOrEqual: op = ">="; break;
case ExpressionType.LessThan: op = "<"; break;
case ExpressionType.LessThanOrEqual: op = "<="; break;
-
+
// Comparisons against 'NULL' require the 'IS' or 'IS NOT' operator instead the numeric ones...
case ExpressionType.Equal: op = node.Right == null && !VirtualMode ? "IS" : "="; break;
case ExpressionType.NotEqual: op = node.Right == null && !VirtualMode ? "IS NOT" : "<>"; break;
-
+
default: throw new ArgumentException("Not supported operator: '" + node.Operation);
}
-
+
DynamicSchemaColumn? columnSchema = null;
- string left = Parse(node.Left, ref columnSchema, pars); // Not nulls: left is assumed to be an object
+ string left = Parse(node.Left, ref columnSchema,
+ pars); // Not nulls: left is assumed to be an object
string right = Parse(node.Right, ref columnSchema, pars, nulls: true);
return string.Format("({0} {1} {2})", left, op, right);
}
-
- protected virtual string ParseMethod(DynamicParser.Node.Method node, ref DynamicSchemaColumn? columnSchema, IDictionary pars = null)
+
+ protected virtual string ParseMethod(DynamicParser.Node.Method node,
+ ref DynamicSchemaColumn? columnSchema, IDictionary pars = null)
{
string method = node.Name.ToUpper();
string parent = node.Host == null ? null : Parse(node.Host, ref columnSchema, pars: pars);
string item = null;
-
+
// Root-level methods...
if (node.Host == null)
{
switch (method)
{
case "NOT":
- if (node.Arguments == null || node.Arguments.Length != 1) throw new ArgumentNullException("NOT method expects one argument: " + node.Arguments.Sketch());
+ if (node.Arguments == null || node.Arguments.Length != 1)
+ throw new ArgumentNullException("NOT method expects one argument: " +
+ node.Arguments.Sketch());
item = Parse(node.Arguments[0], ref columnSchema, pars: pars);
return string.Format("(NOT {0})", item);
}
}
-
+
// Column-level methods...
if (node.Host != null)
{
switch (method)
{
case "BETWEEN":
+ {
+ if (node.Arguments == null || node.Arguments.Length == 0)
+ throw new ArgumentException("BETWEEN method expects at least one argument: " +
+ node.Arguments.Sketch());
+
+ if (node.Arguments.Length > 2)
+ throw new ArgumentException("BETWEEN method expects at most two arguments: " +
+ node.Arguments.Sketch());
+
+ object[] arguments = node.Arguments;
+
+ if (arguments.Length == 1 &&
+ (arguments[0] is IEnumerable || arguments[0] is Array) &&
+ !(arguments[0] is byte[]))
{
- if (node.Arguments == null || node.Arguments.Length == 0)
- throw new ArgumentException("BETWEEN method expects at least one argument: " + node.Arguments.Sketch());
-
- if (node.Arguments.Length > 2)
- throw new ArgumentException("BETWEEN method expects at most two arguments: " + node.Arguments.Sketch());
-
- object[] arguments = node.Arguments;
-
- if (arguments.Length == 1 && (arguments[0] is IEnumerable || arguments[0] is Array) && !(arguments[0] is byte[]))
- {
- IEnumerable vals = arguments[0] as IEnumerable;
-
- if (vals == null && arguments[0] is Array)
- vals = ((Array)arguments[0]).Cast() as IEnumerable;
-
- if (vals != null)
- arguments = vals.ToArray();
- else
- throw new ArgumentException("BETWEEN method expects single argument to be enumerable of exactly two elements: " + node.Arguments.Sketch());
- }
-
- return string.Format("{0} BETWEEN {1} AND {2}", parent, Parse(arguments[0], ref columnSchema, pars: pars), Parse(arguments[1], ref columnSchema, pars: pars));
+ IEnumerable vals = arguments[0] as IEnumerable;
+
+ if (vals == null && arguments[0] is Array)
+ vals = ((Array)arguments[0]).Cast() as IEnumerable;
+
+ if (vals != null)
+ arguments = vals.ToArray();
+ else
+ throw new ArgumentException(
+ "BETWEEN method expects single argument to be enumerable of exactly two elements: " +
+ node.Arguments.Sketch());
}
-
+
+ return string.Format("{0} BETWEEN {1} AND {2}", parent,
+ Parse(arguments[0], ref columnSchema, pars: pars),
+ Parse(arguments[1], ref columnSchema, pars: pars));
+ }
+
case "IN":
+ {
+ if (node.Arguments == null || node.Arguments.Length == 0)
+ throw new ArgumentException("IN method expects at least one argument: " +
+ node.Arguments.Sketch());
+
+ bool firstParam = true;
+ StringBuilder sbin = new StringBuilder();
+ foreach (object arg in node.Arguments)
{
- if (node.Arguments == null || node.Arguments.Length == 0)
- throw new ArgumentException("IN method expects at least one argument: " + node.Arguments.Sketch());
-
- bool firstParam = true;
- StringBuilder sbin = new StringBuilder();
- foreach (object arg in node.Arguments)
+ if (!firstParam)
+ sbin.Append(", ");
+
+ if ((arg is IEnumerable || arg is Array) && !(arg is byte[]))
{
- if (!firstParam)
- sbin.Append(", ");
-
- if ((arg is IEnumerable || arg is Array) && !(arg is byte[]))
- {
- IEnumerable vals = arg as IEnumerable;
-
- if (vals == null && arg is Array)
- vals = ((Array)arg).Cast() as IEnumerable;
-
- if (vals != null)
- foreach (object val in vals)
- {
- if (!firstParam)
- sbin.Append(", ");
- else
- firstParam = false;
-
- sbin.Append(Parse(val, ref columnSchema, pars: pars));
- }
- else
- sbin.Append(Parse(arg, ref columnSchema, pars: pars));
- }
+ IEnumerable vals = arg as IEnumerable;
+
+ if (vals == null && arg is Array)
+ vals = ((Array)arg).Cast() as IEnumerable;
+
+ if (vals != null)
+ foreach (object val in vals)
+ {
+ if (!firstParam)
+ sbin.Append(", ");
+ else
+ firstParam = false;
+
+ sbin.Append(Parse(val, ref columnSchema, pars: pars));
+ }
else
sbin.Append(Parse(arg, ref columnSchema, pars: pars));
-
- firstParam = false;
}
-
- return string.Format("{0} IN({1})", parent, sbin.ToString());
+ else
+ sbin.Append(Parse(arg, ref columnSchema, pars: pars));
+
+ firstParam = false;
}
-
+
+ return string.Format("{0} IN({1})", parent, sbin.ToString());
+ }
+
case "NOTIN":
+ {
+ if (node.Arguments == null || node.Arguments.Length == 0)
+ throw new ArgumentException("IN method expects at least one argument: " +
+ node.Arguments.Sketch());
+
+ bool firstParam = true;
+ StringBuilder sbin = new StringBuilder();
+ foreach (object arg in node.Arguments)
{
- if (node.Arguments == null || node.Arguments.Length == 0)
- throw new ArgumentException("IN method expects at least one argument: " + node.Arguments.Sketch());
-
- bool firstParam = true;
- StringBuilder sbin = new StringBuilder();
- foreach (object arg in node.Arguments)
+ if (!firstParam)
+ sbin.Append(", ");
+
+ if ((arg is IEnumerable || arg is Array) && !(arg is byte[]))
{
- if (!firstParam)
- sbin.Append(", ");
-
- if ((arg is IEnumerable || arg is Array) && !(arg is byte[]))
- {
- IEnumerable vals = arg as IEnumerable;
-
- if (vals == null && arg is Array)
- vals = ((Array)arg).Cast() as IEnumerable;
-
- if (vals != null)
- foreach (object val in vals)
- {
- if (!firstParam)
- sbin.Append(", ");
- else
- firstParam = false;
-
- sbin.Append(Parse(val, ref columnSchema, pars: pars));
- }
- else
- sbin.Append(Parse(arg, ref columnSchema, pars: pars));
- }
+ IEnumerable vals = arg as IEnumerable;
+
+ if (vals == null && arg is Array)
+ vals = ((Array)arg).Cast() as IEnumerable;
+
+ if (vals != null)
+ foreach (object val in vals)
+ {
+ if (!firstParam)
+ sbin.Append(", ");
+ else
+ firstParam = false;
+
+ sbin.Append(Parse(val, ref columnSchema, pars: pars));
+ }
else
sbin.Append(Parse(arg, ref columnSchema, pars: pars));
-
- firstParam = false;
}
-
- return string.Format("{0} NOT IN({1})", parent, sbin.ToString());
+ else
+ sbin.Append(Parse(arg, ref columnSchema, pars: pars));
+
+ firstParam = false;
}
-
+
+ return string.Format("{0} NOT IN({1})", parent, sbin.ToString());
+ }
+
case "LIKE":
if (node.Arguments == null || node.Arguments.Length != 1)
- throw new ArgumentException("LIKE method expects one argument: " + node.Arguments.Sketch());
-
- return string.Format("{0} LIKE {1}", parent, Parse(node.Arguments[0], ref columnSchema, pars: pars));
-
+ throw new ArgumentException("LIKE method expects one argument: " +
+ node.Arguments.Sketch());
+
+ return string.Format("{0} LIKE {1}", parent,
+ Parse(node.Arguments[0], ref columnSchema, pars: pars));
+
case "NOTLIKE":
if (node.Arguments == null || node.Arguments.Length != 1)
- throw new ArgumentException("NOT LIKE method expects one argument: " + node.Arguments.Sketch());
-
- return string.Format("{0} NOT LIKE {1}", parent, Parse(node.Arguments[0], ref columnSchema, pars: pars));
-
+ throw new ArgumentException("NOT LIKE method expects one argument: " +
+ node.Arguments.Sketch());
+
+ return string.Format("{0} NOT LIKE {1}", parent,
+ Parse(node.Arguments[0], ref columnSchema, pars: pars));
+
case "AS":
if (node.Arguments == null || node.Arguments.Length != 1)
- throw new ArgumentException("AS method expects one argument: " + node.Arguments.Sketch());
-
- item = Parse(node.Arguments[0], pars: null, rawstr: true, isMultiPart: false); // pars=null to avoid to parameterize aliases
+ throw new ArgumentException("AS method expects one argument: " +
+ node.Arguments.Sketch());
+
+ item = Parse(node.Arguments[0], pars: null, rawstr: true,
+ isMultiPart: false); // pars=null to avoid to parameterize aliases
item = item.Validated("Alias"); // Intercepting null and empty aliases
return string.Format("{0} AS {1}", parent, item);
-
+
case "NOLOCK":
if (!SupportNoLock)
return parent;
-
+
if (node.Arguments != null && node.Arguments.Length > 1)
throw new ArgumentException("NOLOCK method expects no arguments.");
-
+
return string.Format("{0} {1}", parent, "WITH(NOLOCK)");
-
+
case "COUNT":
if (node.Arguments != null && node.Arguments.Length > 1)
- throw new ArgumentException("COUNT method expects one or none argument: " + node.Arguments.Sketch());
-
+ throw new ArgumentException("COUNT method expects one or none argument: " +
+ node.Arguments.Sketch());
+
if (node.Arguments == null || node.Arguments.Length == 0)
return "COUNT(*)";
-
- return string.Format("COUNT({0})", Parse(node.Arguments[0], ref columnSchema, pars: Parameters, nulls: true));
-
+
+ return string.Format("COUNT({0})",
+ Parse(node.Arguments[0], ref columnSchema, pars: Parameters, nulls: true));
+
case "COUNT0":
if (node.Arguments != null && node.Arguments.Length > 0)
throw new ArgumentException("COUNT0 method doesn't expect arguments");
-
+
return "COUNT(0)";
}
}
-
+
// Default case: parsing the method's name along with its arguments...
method = parent == null ? node.Name : string.Format("{0}.{1}", parent, node.Name);
StringBuilder sb = new StringBuilder();
sb.AppendFormat("{0}(", method);
-
+
if (node.Arguments != null && node.Arguments.Length != 0)
{
bool first = true;
-
+
foreach (object argument in node.Arguments)
{
if (!first)
sb.Append(", ");
else
first = false;
-
- sb.Append(Parse(argument, ref columnSchema, pars, nulls: true)); // We don't accept raw strings here!!!
+
+ sb.Append(Parse(argument, ref columnSchema, pars,
+ nulls: true)); // We don't accept raw strings here!!!
}
}
-
+
sb.Append(")");
return sb.ToString();
}
-
- protected virtual string ParseInvoke(DynamicParser.Node.Invoke node, ref DynamicSchemaColumn? columnSchema, IDictionary pars = null)
+
+ protected virtual string ParseInvoke(DynamicParser.Node.Invoke node,
+ ref DynamicSchemaColumn? columnSchema, IDictionary pars = null)
{
// This is used as an especial syntax to merely concatenate its arguments. It is used as a way to extend the supported syntax without the need of treating all the possible cases...
if (node.Arguments == null || node.Arguments.Length == 0)
return string.Empty;
-
+
StringBuilder sb = new StringBuilder();
foreach (object arg in node.Arguments)
{
if (arg is string)
{
sb.Append((string)arg);
-
+
if (node.Arguments.Length == 1 && !columnSchema.HasValue)
columnSchema = GetColumnFromSchema((string)arg);
}
else
sb.Append(Parse(arg, ref columnSchema, pars, rawstr: true, nulls: true));
}
-
+
return sb.ToString();
}
-
- protected virtual string ParseConvert(DynamicParser.Node.Convert node, IDictionary pars = null)
+
+ protected virtual string ParseConvert(DynamicParser.Node.Convert node,
+ IDictionary pars = null)
{
// The cast mechanism is left for the specific database implementation, that should override this method
// as needed...
string r = Parse(node.Target, pars);
return r;
}
-
- protected virtual string ParseConstant(object node, IDictionary pars = null, DynamicSchemaColumn? columnSchema = null)
+
+ protected virtual string ParseConstant(object node, IDictionary pars = null,
+ DynamicSchemaColumn? columnSchema = null)
{
if (node == null && !VirtualMode)
return ParseNull();
-
+
if (pars != null)
{
- bool wellKnownName = VirtualMode && node is String && ((String)node).StartsWith("[$") && ((String)node).EndsWith("]") && ((String)node).Length > 4;
-
+ bool wellKnownName = VirtualMode && node is String && ((String)node).StartsWith("[$") &&
+ ((String)node).EndsWith("]") && ((String)node).Length > 4;
+
// If we have a list of parameters to store it, let's parametrize it
Parameter par = new Parameter()
{
- Name = wellKnownName ? ((String)node).Substring(2, ((String)node).Length - 3) : Guid.NewGuid().ToString(),
+ Name = wellKnownName
+ ? ((String)node).Substring(2, ((String)node).Length - 3)
+ : Guid.NewGuid().ToString(),
Value = wellKnownName ? null : node,
WellKnown = wellKnownName,
Virtual = VirtualMode,
Schema = columnSchema,
};
-
+
// If we are adding parameter we inform external sources about this.
if (OnCreateTemporaryParameter != null)
OnCreateTemporaryParameter.ForEach(x => x(par));
-
+
pars.Add(par.Name, par);
-
+
return string.Format("[${0}]", par.Name);
}
-
+
return node.ToString(); // Last resort case
}
-
+
protected virtual string ParseNull()
{
return "NULL"; // Override if needed
}
-
+
#endregion Parser
-
+
#region Helpers
-
+
internal bool IsTableAlias(string name)
{
DynamicQueryBuilder builder = this;
-
+
while (builder != null)
{
if (builder.Tables.Any(t => t.Alias == name))
return true;
-
+
builder = builder._parent;
}
-
+
return false;
}
-
+
internal bool IsTable(string name, string owner)
{
DynamicQueryBuilder builder = this;
-
+
while (builder != null)
{
- if ((string.IsNullOrEmpty(owner) && builder.Tables.Any(t => t.Name.ToLower() == name.ToLower())) ||
- (!string.IsNullOrEmpty(owner) && builder.Tables.Any(t => t.Name.ToLower() == name.ToLower() &&
+ if ((string.IsNullOrEmpty(owner) &&
+ builder.Tables.Any(t => t.Name.ToLower() == name.ToLower())) ||
+ (!string.IsNullOrEmpty(owner) && builder.Tables.Any(t =>
+ t.Name.ToLower() == name.ToLower() &&
!string.IsNullOrEmpty(t.Owner) && t.Owner.ToLower() == owner.ToLower())))
return true;
-
+
builder = builder._parent;
}
-
+
return false;
}
-
+
internal string FixObjectName(string main, bool onlyColumn = false)
{
if (main.IndexOf("(") > 0 && main.IndexOf(")") > 0)
- return main.FillStringWithVariables(f => string.Format("({0})", FixObjectNamePrivate(f, onlyColumn)), "(", ")");
+ return main.FillStringWithVariables(
+ f => string.Format("({0})", FixObjectNamePrivate(f, onlyColumn)), "(", ")");
else
return FixObjectNamePrivate(main, onlyColumn);
}
-
+
private string FixObjectNamePrivate(string f, bool onlyColumn = false)
{
IEnumerable objects = f.Split('.')
.Select(x => Database.StripName(x));
-
+
if (onlyColumn || objects.Count() == 1)
f = Database.DecorateName(objects.Last());
else if (!IsTableAlias(objects.First()))
f = string.Join(".", objects.Select(o => Database.DecorateName(o)));
else
- f = string.Format("{0}.{1}", objects.First(), string.Join(".", objects.Skip(1).Select(o => Database.DecorateName(o))));
-
+ f = string.Format("{0}.{1}", objects.First(),
+ string.Join(".", objects.Skip(1).Select(o => Database.DecorateName(o))));
+
return f;
}
-
- internal DynamicSchemaColumn? GetColumnFromSchema(string colName, DynamicTypeMap mapper = null, string table = null)
+
+ internal DynamicSchemaColumn? GetColumnFromSchema(string colName, DynamicTypeMap mapper = null,
+ string table = null)
{
// This is tricky and will not always work unfortunetly.
////if (colName.ContainsAny(StringExtensions.InvalidMultipartMemberChars))
//// return null;
-
+
// First we need to get real column name and it's owner if exist.
string[] parts = colName.Split('.');
for (int i = 0; i < parts.Length; i++)
parts[i] = Database.StripName(parts[i]);
-
+
string columnName = parts.Last();
-
+
// Get table name from mapper
string tableName = table;
-
+
if (string.IsNullOrEmpty(tableName))
{
tableName = (mapper != null && mapper.Table != null) ? mapper.Table.Name : string.Empty;
-
+
if (parts.Length > 1 && string.IsNullOrEmpty(tableName))
{
// OK, we have a multi part identifier, that's good, we can get table name
tableName = string.Join(".", parts.Take(parts.Length - 1));
}
}
-
+
// Try to get table info from cache
- ITableInfo tableInfo = !string.IsNullOrEmpty(tableName) ?
+ ITableInfo tableInfo = !string.IsNullOrEmpty(tableName)
+ ?
Tables.FirstOrDefault(x => !string.IsNullOrEmpty(x.Alias) && x.Alias.ToLower() == tableName) ??
- Tables.FirstOrDefault(x => x.Name.ToLower() == tableName.ToLower()) ?? Tables.FirstOrDefault() :
- this is DynamicModifyBuilder || Tables.Count == 1 ? Tables.FirstOrDefault() : null;
-
+ Tables.FirstOrDefault(x => x.Name.ToLower() == tableName.ToLower()) ?? Tables.FirstOrDefault()
+ :
+ this is DynamicModifyBuilder || Tables.Count == 1
+ ? Tables.FirstOrDefault()
+ : null;
+
// Try to get column from schema
if (tableInfo != null && tableInfo.Schema != null)
return tableInfo.Schema.TryGetNullable(columnName.ToLower());
-
+
// Well, we failed to find a column
return null;
}
-
+
#endregion Helpers
-
+
#region IExtendedDisposable
-
+
/// Gets a value indicating whether this instance is disposed.
public bool IsDisposed { get; private set; }
-
+
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
public virtual void Dispose()
{
IsDisposed = true;
-
+
if (Database != null)
Database.RemoveFromCache(this);
-
+
if (Parameters != null)
{
foreach (KeyValuePair p in Parameters)
p.Value.Dispose();
-
+
Parameters.Clear();
Parameters = null;
}
-
+
if (Tables != null)
{
foreach (ITableInfo t in Tables)
if (t != null)
t.Dispose();
-
+
Tables.Clear();
Tables = null;
}
-
+
WhereCondition = null;
Database = null;
}
-
+
#endregion IExtendedDisposable
}
-
+
/// Implementation of dynamic select query builder.
- internal class DynamicSelectQueryBuilder : DynamicQueryBuilder, IDynamicSelectQueryBuilder, DynamicQueryBuilder.IQueryWithWhere, DynamicQueryBuilder.IQueryWithHaving
+ internal class DynamicSelectQueryBuilder : DynamicQueryBuilder, IDynamicSelectQueryBuilder,
+ DynamicQueryBuilder.IQueryWithWhere, DynamicQueryBuilder.IQueryWithHaving
{
private int? _limit = null;
private int? _offset = null;
private bool _distinct = false;
-
+
private string _select;
private string _from;
private string _join;
private string _groupby;
private string _orderby;
-
+
#region IQueryWithHaving
-
+
/// Gets or sets the having condition.
public string HavingCondition { get; set; }
-
+
/// Gets or sets the amount of not closed brackets in having statement.
public int HavingOpenBracketsCount { get; set; }
-
+
#endregion IQueryWithHaving
-
+
///
/// Gets a value indicating whether this instance has select columns.
///
- public bool HasSelectColumns { get { return !string.IsNullOrEmpty(_select); } }
-
+ public bool HasSelectColumns
+ {
+ get { return !string.IsNullOrEmpty(_select); }
+ }
+
///
/// Initializes a new instance of the class.
///
@@ -9539,7 +9950,7 @@ namespace DynamORM
: base(db)
{
}
-
+
///
/// Initializes a new instance of the class.
///
@@ -9549,17 +9960,17 @@ namespace DynamORM
: base(db, parent)
{
}
-
+
/// Generates the text this command will execute against the underlying database.
/// The text to execute against the underlying database.
public override string CommandText()
{
bool lused = false;
bool oused = false;
-
+
StringBuilder sb = new StringBuilder("SELECT");
if (_distinct) sb.AppendFormat(" DISTINCT");
-
+
if (_limit.HasValue)
{
if ((Database.Options & DynamicDatabaseOptions.SupportTop) == DynamicDatabaseOptions.SupportTop)
@@ -9567,116 +9978,119 @@ namespace DynamORM
sb.AppendFormat(" TOP {0}", _limit);
lused = true;
}
- else if ((Database.Options & DynamicDatabaseOptions.SupportFirstSkip) == DynamicDatabaseOptions.SupportFirstSkip)
+ else if ((Database.Options & DynamicDatabaseOptions.SupportFirstSkip) ==
+ DynamicDatabaseOptions.SupportFirstSkip)
{
sb.AppendFormat(" FIRST {0}", _limit);
lused = true;
}
}
-
- if (_offset.HasValue && (Database.Options & DynamicDatabaseOptions.SupportFirstSkip) == DynamicDatabaseOptions.SupportFirstSkip)
+
+ 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 (_join != null) sb.AppendFormat(" {0}", _join);
if (WhereCondition != null) sb.AppendFormat(" WHERE {0}", WhereCondition);
if (_groupby != null) sb.AppendFormat(" GROUP BY {0}", _groupby);
if (HavingCondition != null) sb.AppendFormat(" HAVING {0}", HavingCondition);
if (_orderby != null) sb.AppendFormat(" ORDER BY {0}", _orderby);
- if (_limit.HasValue && !lused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
+ if (_limit.HasValue && !lused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) ==
+ DynamicDatabaseOptions.SupportLimitOffset)
sb.AppendFormat(" LIMIT {0}", _limit);
- if (_offset.HasValue && !oused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) == DynamicDatabaseOptions.SupportLimitOffset)
+ if (_offset.HasValue && !oused && (Database.Options & DynamicDatabaseOptions.SupportLimitOffset) ==
+ DynamicDatabaseOptions.SupportLimitOffset)
sb.AppendFormat(" OFFSET {0}", _offset);
-
+
return sb.ToString();
}
-
+
#region Execution
-
+
/// Execute this builder.
/// Enumerator of objects expanded from query.
public virtual IEnumerable Execute()
{
- DynamicCachedReader cache = null;
using (IDbConnection con = Database.Open())
using (IDbCommand cmd = con.CreateCommand())
{
using (IDataReader rdr = cmd
- .SetCommand(this)
- .ExecuteReader())
- cache = new DynamicCachedReader(rdr);
-
- while (cache.Read())
- {
- dynamic val = null;
-
- // Work around to avoid yield being in try...catchblock:
- // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
- try
+ .SetCommand(this)
+ .ExecuteReader())
+ using (IDataReader cache = new DynamicCachedReader(rdr))
+ while (cache.Read())
{
- val = cache.RowToDynamic();
+ dynamic val = null;
+
+ // Work around to avoid yield being in try...catchblock:
+ // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
+ try
+ {
+ val = cache.RowToDynamic();
+ }
+ catch (ArgumentException argex)
+ {
+ StringBuilder sb = new StringBuilder();
+ cmd.Dump(sb);
+
+ throw new ArgumentException(
+ string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
+ argex.InnerException.NullOr(a => a, argex));
+ }
+
+ yield return val;
}
- catch (ArgumentException argex)
- {
- StringBuilder sb = new StringBuilder();
- cmd.Dump(sb);
-
- throw new ArgumentException(string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
- argex.InnerException.NullOr(a => a, argex));
- }
-
- yield return val;
- }
}
}
-
+
/// Execute this builder and map to given type.
/// Type of object to map on.
/// Enumerator of objects expanded from query.
public virtual IEnumerable Execute() where T : class
{
- DynamicCachedReader cache = null;
DynamicTypeMap mapper = DynamicMapperCache.GetMapper();
-
+
if (mapper == null)
throw new InvalidOperationException("Type can't be mapped for unknown reason.");
-
+
using (IDbConnection con = Database.Open())
using (IDbCommand cmd = con.CreateCommand())
{
using (IDataReader rdr = cmd
- .SetCommand(this)
- .ExecuteReader())
- cache = new DynamicCachedReader(rdr);
-
- while (cache.Read())
- {
- dynamic val = null;
-
- // Work around to avoid yield being in try...catchblock:
- // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
- try
+ .SetCommand(this)
+ .ExecuteReader())
+ using (IDataReader cache = new DynamicCachedReader(rdr))
+ while (cache.Read())
{
- val = cache.RowToDynamic();
+ dynamic val = null;
+
+ // Work around to avoid yield being in try...catchblock:
+ // http://stackoverflow.com/questions/346365/why-cant-yield-return-appear-inside-a-try-block-with-a-catch
+ try
+ {
+ val = cache.RowToDynamic();
+ }
+ catch (ArgumentException argex)
+ {
+ StringBuilder sb = new StringBuilder();
+ cmd.Dump(sb);
+
+ throw new ArgumentException(
+ string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
+ argex.InnerException.NullOr(a => a, argex));
+ }
+
+ yield return mapper.Create(val) as T;
}
- catch (ArgumentException argex)
- {
- StringBuilder sb = new StringBuilder();
- cmd.Dump(sb);
-
- throw new ArgumentException(string.Format("{0}{1}{2}", argex.Message, Environment.NewLine, sb),
- argex.InnerException.NullOr(a => a, argex));
- }
-
- yield return mapper.Create(val) as T;
- }
}
}
-
+
/// Execute this builder as a data reader.
/// Action containing reader.
public virtual void ExecuteDataReader(Action reader)
@@ -9684,28 +10098,25 @@ namespace DynamORM
using (IDbConnection con = Database.Open())
using (IDbCommand cmd = con.CreateCommand())
using (IDataReader rdr = cmd
- .SetCommand(this)
- .ExecuteReader())
+ .SetCommand(this)
+ .ExecuteReader())
reader(rdr);
}
-
+
/// Execute this builder as a data reader, but
/// first makes a full reader copy in memory.
/// Action containing reader.
public virtual void ExecuteCachedDataReader(Action reader)
{
- DynamicCachedReader cache = null;
-
using (IDbConnection con = Database.Open())
using (IDbCommand cmd = con.CreateCommand())
using (IDataReader rdr = cmd
- .SetCommand(this)
- .ExecuteReader())
- cache = new DynamicCachedReader(rdr);
-
- reader(cache);
+ .SetCommand(this)
+ .ExecuteReader())
+ using (IDataReader cache = new DynamicCachedReader(rdr))
+ reader(cache);
}
-
+
/// Returns a single result.
/// Result of a query.
public virtual object Scalar()
@@ -9718,9 +10129,9 @@ namespace DynamORM
.ExecuteScalar();
}
}
-
- #if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
-
+
+#if !DYNAMORM_OMMIT_GENERICEXECUTION && !DYNAMORM_OMMIT_TRYPARSE
+
/// Returns a single result.
/// Type to parse to.
/// Default value.
@@ -9735,13 +10146,13 @@ namespace DynamORM
.ExecuteScalarAs(defaultValue);
}
}
-
- #endif
-
+
+#endif
+
#endregion Execution
-
+
#region From/Join
-
+
///
/// Adds to the 'From' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -9753,29 +10164,30 @@ namespace DynamORM
/// The specification.
/// The specification.
/// This instance to permit chaining.
- public virtual IDynamicSelectQueryBuilder From(Func fn, params Func[] func)
+ public virtual IDynamicSelectQueryBuilder From(Func fn,
+ params Func[] func)
{
if (fn == null)
throw new ArgumentNullException("Array of functions cannot be or contain null.");
-
+
int index = FromFunc(-1, fn);
foreach (Func f in func)
index = FromFunc(index, f);
-
+
return this;
}
-
+
private int FromFunc(int index, Func f)
{
if (f == null)
throw new ArgumentNullException("Array of functions cannot be or contain null.");
-
+
index++;
ITableInfo tableInfo = null;
using (DynamicParser parser = DynamicParser.Parse(f))
{
object result = parser.Result;
-
+
// If the expression result is string.
if (result is string)
{
@@ -9785,95 +10197,105 @@ namespace DynamORM
tableInfo = new TableInfo(Database,
Database.StripName(parts.Last()).Validated("Table"),
tuple.Item2.Validated("Alias", canbeNull: true),
- parts.Length == 2 ? Database.StripName(parts.First()).Validated("Owner", canbeNull: true) : null);
+ parts.Length == 2
+ ? Database.StripName(parts.First()).Validated("Owner", canbeNull: true)
+ : null);
}
else if (result is Type)
{
Type type = (Type)result;
if (type.IsAnonymous())
- throw new InvalidOperationException(string.Format("Cant assign anonymous type as a table ({0}). Parsing {1}", type.FullName, result));
-
+ throw new InvalidOperationException(string.Format(
+ "Cant assign anonymous type as a table ({0}). Parsing {1}", type.FullName, result));
+
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
-
+
if (mapper == null)
- throw new InvalidOperationException(string.Format("Cant assign unmapable type as a table ({0}). Parsing {1}", type.FullName, result));
-
+ throw new InvalidOperationException(string.Format(
+ "Cant assign unmapable type as a table ({0}). Parsing {1}", type.FullName, result));
+
tableInfo = new TableInfo(Database, type);
}
else if (result is DynamicParser.Node)
{
// Or if it resolves to a dynamic node
DynamicParser.Node node = (DynamicParser.Node)result;
-
+
string owner = null;
string main = null;
string alias = null;
bool nolock = false;
Type type = null;
-
+
while (true)
{
// Support for the AS() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
{
if (alias != null)
- throw new ArgumentException(string.Format("Alias '{0}' is already set when parsing '{1}'.", alias, result));
-
+ throw new ArgumentException(string.Format(
+ "Alias '{0}' is already set when parsing '{1}'.", alias, result));
+
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args == null)
throw new ArgumentNullException("arg", "AS() is not a parameterless method.");
-
+
if (args.Length != 1)
- throw new ArgumentException("AS() requires one and only one parameter: " + args.Sketch());
-
+ throw new ArgumentException("AS() requires one and only one parameter: " +
+ args.Sketch());
+
alias = Parse(args[0], rawstr: true, decorate: false).Validated("Alias");
-
+
node = node.Host;
continue;
}
-
+
// Support for the NoLock() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
{
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args != null && args.Length > 0)
throw new ArgumentNullException("arg", "NoLock() doesn't support arguments.");
-
+
nolock = true;
-
+
node = node.Host;
continue;
}
-
+
/*if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "subquery")
{
main = Parse(this.SubQuery(((DynamicParser.Node.Method)node).Arguments.Where(p => p is Func).Cast>().ToArray()), Parameters);
continue;
}*/
-
+
// Support for table specifications...
if (node is DynamicParser.Node.GetMember)
{
if (owner != null)
- throw new ArgumentException(string.Format("Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
-
+ throw new ArgumentException(string.Format(
+ "Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
+
if (main != null)
owner = ((DynamicParser.Node.GetMember)node).Name;
else
main = ((DynamicParser.Node.GetMember)node).Name;
-
+
node = node.Host;
continue;
}
-
+
// Support for generic sources...
if (node is DynamicParser.Node.Invoke)
{
if (owner != null)
- throw new ArgumentException(string.Format("Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
-
+ throw new ArgumentException(string.Format(
+ "Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
+
if (main != null)
owner = string.Format("{0}", Parse(node, rawstr: true, pars: Parameters));
else
@@ -9883,70 +10305,85 @@ namespace DynamORM
{
type = (Type)invoke.Arguments[0];
if (type.IsAnonymous())
- throw new InvalidOperationException(string.Format("Cant assign anonymous type as a table ({0}). Parsing {1}", type.FullName, result));
-
+ throw new InvalidOperationException(
+ string.Format(
+ "Cant assign anonymous type as a table ({0}). Parsing {1}",
+ type.FullName, result));
+
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(type);
-
+
if (mapper == null)
- throw new InvalidOperationException(string.Format("Cant assign unmapable type as a table ({0}). Parsing {1}", type.FullName, result));
-
- main = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
- mapper.Type.Name : mapper.Table.Name;
-
+ throw new InvalidOperationException(
+ string.Format(
+ "Cant assign unmapable type as a table ({0}). Parsing {1}",
+ type.FullName, result));
+
+ main = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name)
+ ? mapper.Type.Name
+ : mapper.Table.Name;
+
owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
}
else
main = string.Format("{0}", Parse(node, rawstr: true, pars: Parameters));
}
-
+
node = node.Host;
continue;
}
-
+
// Just finished the parsing...
if (node is DynamicParser.Node.Argument) break;
-
+
// All others are assumed to be part of the main element...
if (main != null)
main = Parse(node, pars: Parameters);
else
main = Parse(node, pars: Parameters);
-
+
break;
}
-
+
if (!string.IsNullOrEmpty(main))
- tableInfo = type == null ? new TableInfo(Database, main, alias, owner, nolock) : new TableInfo(Database, type, alias, owner, nolock);
+ tableInfo = type == null
+ ? new TableInfo(Database, main, alias, owner, nolock)
+ : new TableInfo(Database, type, alias, owner, nolock);
else
- throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
+ throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index,
+ result));
}
-
+
// Or it is a not supported expression...
if (tableInfo == null)
- throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
-
+ throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index,
+ result));
+
Tables.Add(tableInfo);
-
+
// We finally add the contents...
StringBuilder sb = new StringBuilder();
-
+
if (!string.IsNullOrEmpty(tableInfo.Owner))
sb.AppendFormat("{0}.", Database.DecorateName(tableInfo.Owner));
-
- sb.Append(tableInfo.Name.ContainsAny(StringExtensions.InvalidMemberChars) ? tableInfo.Name : Database.DecorateName(tableInfo.Name));
-
+
+ sb.Append(tableInfo.Name.ContainsAny(StringExtensions.InvalidMemberChars)
+ ? tableInfo.Name
+ : Database.DecorateName(tableInfo.Name));
+
if (!string.IsNullOrEmpty(tableInfo.Alias))
sb.AppendFormat(" AS {0}", tableInfo.Alias);
-
+
if (SupportNoLock && tableInfo.NoLock)
sb.AppendFormat(" WITH(NOLOCK)");
-
- _from = string.IsNullOrEmpty(_from) ? sb.ToString() : string.Format("{0}, {1}", _from, sb.ToString());
+
+ _from = string.IsNullOrEmpty(_from)
+ ? sb.ToString()
+ : string.Format("{0}, {1}", _from, sb.ToString());
}
-
+
return index;
}
-
+
///
/// Adds to the 'Join' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -9968,7 +10405,7 @@ namespace DynamORM
// We need to do two passes to add aliases first.
return JoinInternal(true, func).JoinInternal(false, func);
}
-
+
///
/// Adds to the 'Join' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -9986,25 +10423,28 @@ namespace DynamORM
/// If true just pass by to locate tables and aliases, otherwise create rules.
/// The specification.
/// This instance to permit chaining.
- protected virtual DynamicSelectQueryBuilder JoinInternal(bool justAddTables, params Func[] func)
+ protected virtual DynamicSelectQueryBuilder JoinInternal(bool justAddTables,
+ params Func[] func)
{
if (func == null) throw new ArgumentNullException("Array of functions cannot be null.");
-
+
int index = -1;
-
+
foreach (Func f in func)
{
index++;
ITableInfo tableInfo = null;
-
+
if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
-
+
using (DynamicParser parser = DynamicParser.Parse(f))
{
object result = parser.Result;
- if (result == null) throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
-
+ if (result == null)
+ throw new ArgumentException(
+ string.Format("Specification #{0} resolves to null.", index));
+
string type = null;
string main = null;
string owner = null;
@@ -10012,14 +10452,14 @@ namespace DynamORM
string condition = null;
bool nolock = false;
Type tableType = null;
-
+
// If the expression resolves to a string...
if (result is string)
{
string node = (string)result;
-
+
int n = node.ToUpper().IndexOf("JOIN ");
-
+
if (n < 0)
main = node;
else
@@ -10028,19 +10468,23 @@ namespace DynamORM
type = node.Substring(0, n + 4);
main = node.Substring(n + 4);
}
-
+
n = main.ToUpper().IndexOf("ON");
-
+
if (n >= 0)
{
condition = main.Substring(n + 3);
main = main.Substring(0, n).Trim();
}
-
- Tuple tuple = main.SplitSomethingAndAlias(); // In this case we split on the remaining 'main'
+
+ Tuple
+ tuple = main
+ .SplitSomethingAndAlias(); // In this case we split on the remaining 'main'
string[] parts = tuple.Item1.Split('.');
main = Database.StripName(parts.Last()).Validated("Table");
- owner = parts.Length == 2 ? Database.StripName(parts.First()).Validated("Owner", canbeNull: true) : null;
+ owner = parts.Length == 2
+ ? Database.StripName(parts.First()).Validated("Owner", canbeNull: true)
+ : null;
alias = tuple.Item2.Validated("Alias", canbeNull: true);
}
else if (result is DynamicParser.Node)
@@ -10050,82 +10494,100 @@ namespace DynamORM
while (true)
{
// Support for the ON() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "ON")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "ON")
{
if (condition != null)
- throw new ArgumentException(string.Format("Condition '{0}' is already set when parsing '{1}'.", alias, result));
-
+ throw new ArgumentException(string.Format(
+ "Condition '{0}' is already set when parsing '{1}'.", alias, result));
+
object[] args = ((DynamicParser.Node.Method)node).Arguments;
if (args == null)
- throw new ArgumentNullException("arg", "ON() is not a parameterless method.");
-
+ throw new ArgumentNullException("arg",
+ "ON() is not a parameterless method.");
+
if (args.Length != 1)
- throw new ArgumentException("ON() requires one and only one parameter: " + args.Sketch());
-
- condition = Parse(args[0], rawstr: true, pars: justAddTables ? null : Parameters);
-
+ throw new ArgumentException("ON() requires one and only one parameter: " +
+ args.Sketch());
+
+ condition = Parse(args[0], rawstr: true,
+ pars: justAddTables ? null : Parameters);
+
node = node.Host;
continue;
}
-
+
// Support for the AS() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
{
if (alias != null)
- throw new ArgumentException(string.Format("Alias '{0}' is already set when parsing '{1}'.", alias, result));
-
+ throw new ArgumentException(string.Format(
+ "Alias '{0}' is already set when parsing '{1}'.", alias, result));
+
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args == null)
- throw new ArgumentNullException("arg", "AS() is not a parameterless method.");
-
+ throw new ArgumentNullException("arg",
+ "AS() is not a parameterless method.");
+
if (args.Length != 1)
- throw new ArgumentException("AS() requires one and only one parameter: " + args.Sketch());
-
- alias = Parse(args[0], rawstr: true, decorate: false, isMultiPart: false).Validated("Alias");
-
+ throw new ArgumentException("AS() requires one and only one parameter: " +
+ args.Sketch());
+
+ alias = Parse(args[0], rawstr: true, decorate: false, isMultiPart: false)
+ .Validated("Alias");
+
node = node.Host;
continue;
}
-
+
// Support for the NoLock() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "NOLOCK")
{
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args != null && args.Length > 0)
- throw new ArgumentNullException("arg", "NoLock() doesn't support arguments.");
-
+ throw new ArgumentNullException("arg",
+ "NoLock() doesn't support arguments.");
+
nolock = true;
-
+
node = node.Host;
continue;
}
-
+
// Support for table specifications...
if (node is DynamicParser.Node.GetMember)
{
if (owner != null)
- throw new ArgumentException(string.Format("Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
-
+ throw new ArgumentException(string.Format(
+ "Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main,
+ result));
+
if (main != null)
owner = ((DynamicParser.Node.GetMember)node).Name;
else
main = ((DynamicParser.Node.GetMember)node).Name;
-
+
node = node.Host;
continue;
}
-
+
// Support for Join Type specifications...
- if (node is DynamicParser.Node.Method && (node.Host is DynamicParser.Node.Argument || node.Host is DynamicParser.Node.Invoke))
+ if (node is DynamicParser.Node.Method &&
+ (node.Host is DynamicParser.Node.Argument ||
+ node.Host is DynamicParser.Node.Invoke))
{
- if (type != null) throw new ArgumentException(string.Format("Join type '{0}' is already set when parsing '{1}'.", main, result));
+ if (type != null)
+ throw new ArgumentException(string.Format(
+ "Join type '{0}' is already set when parsing '{1}'.", main, result));
type = ((DynamicParser.Node.Method)node).Name;
-
+
bool avoid = false;
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args != null && args.Length > 0)
{
avoid = args[0] is bool && !((bool)args[0]);
@@ -10133,7 +10595,7 @@ namespace DynamORM
if (!string.IsNullOrEmpty(proposedType))
type = proposedType;
}
-
+
type = type.ToUpper(); // Normalizing, and stepping out the trivial case...
if (type != "JOIN")
{
@@ -10142,13 +10604,13 @@ namespace DynamORM
type = type.Replace("OUTER", " OUTER ")
.Replace(" ", " ")
.Trim(' ');
-
+
// x => x.Left()...
int n = type.IndexOf("JOIN");
-
+
if (n < 0 && !avoid)
type += " JOIN";
-
+
// x => x.InnerJoin() / x => x.JoinLeft() ...
else
{
@@ -10159,19 +10621,22 @@ namespace DynamORM
}
}
}
-
+
node = node.Host;
continue;
}
-
+
// Support for generic sources...
if (node is DynamicParser.Node.Invoke)
{
if (owner != null)
- throw new ArgumentException(string.Format("Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main, result));
-
+ throw new ArgumentException(string.Format(
+ "Owner '{0}.{1}' is already set when parsing '{2}'.", owner, main,
+ result));
+
if (main != null)
- owner = string.Format("{0}", Parse(node, rawstr: true, pars: justAddTables ? null : Parameters));
+ owner = string.Format("{0}",
+ Parse(node, rawstr: true, pars: justAddTables ? null : Parameters));
else
{
DynamicParser.Node.Invoke invoke = (DynamicParser.Node.Invoke)node;
@@ -10179,86 +10644,99 @@ namespace DynamORM
{
tableType = (Type)invoke.Arguments[0];
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(tableType);
-
+
if (mapper == null)
- throw new InvalidOperationException(string.Format("Cant assign unmapable type as a table ({0}).", tableType.FullName));
-
- main = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name) ?
- mapper.Type.Name : mapper.Table.Name;
-
+ throw new InvalidOperationException(
+ string.Format("Cant assign unmapable type as a table ({0}).",
+ tableType.FullName));
+
+ main = mapper.Table == null || string.IsNullOrEmpty(mapper.Table.Name)
+ ? mapper.Type.Name
+ : mapper.Table.Name;
+
owner = (mapper.Table != null) ? mapper.Table.Owner : owner;
}
else
- main = string.Format("{0}", Parse(node, rawstr: true, pars: justAddTables ? null : Parameters));
+ main = string.Format("{0}",
+ Parse(node, rawstr: true, pars: justAddTables ? null : Parameters));
}
-
+
node = node.Host;
continue;
}
-
+
// Just finished the parsing...
if (node is DynamicParser.Node.Argument) break;
- throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
+ throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}",
+ index, result));
}
}
else
{
// Or it is a not supported expression...
- throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
+ throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index,
+ result));
}
-
+
// We annotate the aliases being conservative...
main = main.Validated("Main");
-
+
if (justAddTables)
{
if (!string.IsNullOrEmpty(main))
- tableInfo = tableType == null ? new TableInfo(Database, main, alias, owner, nolock) : new TableInfo(Database, tableType, alias, owner, nolock);
+ tableInfo = tableType == null
+ ? new TableInfo(Database, main, alias, owner, nolock)
+ : new TableInfo(Database, tableType, alias, owner, nolock);
else
- throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
-
+ throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}",
+ index, result));
+
Tables.Add(tableInfo);
}
else
{
// Get cached table info
- tableInfo = string.IsNullOrEmpty(alias) ?
- Tables.SingleOrDefault(t => t.Name == main && string.IsNullOrEmpty(t.Alias)) :
- Tables.SingleOrDefault(t => t.Alias == alias);
-
+ tableInfo = string.IsNullOrEmpty(alias)
+ ? Tables.SingleOrDefault(t => t.Name == main && string.IsNullOrEmpty(t.Alias))
+ : Tables.SingleOrDefault(t => t.Alias == alias);
+
// We finally add the contents if we can...
StringBuilder sb = new StringBuilder();
if (string.IsNullOrEmpty(type))
type = "JOIN";
-
+
sb.AppendFormat("{0} ", type);
-
+
if (!string.IsNullOrEmpty(tableInfo.Owner))
sb.AppendFormat("{0}.", Database.DecorateName(tableInfo.Owner));
-
- sb.Append(tableInfo.Name.ContainsAny(StringExtensions.InvalidMemberChars) ? tableInfo.Name : Database.DecorateName(tableInfo.Name));
-
+
+ sb.Append(tableInfo.Name.ContainsAny(StringExtensions.InvalidMemberChars)
+ ? tableInfo.Name
+ : Database.DecorateName(tableInfo.Name));
+
if (!string.IsNullOrEmpty(tableInfo.Alias))
sb.AppendFormat(" AS {0}", tableInfo.Alias);
-
+
if (SupportNoLock && tableInfo.NoLock)
sb.AppendFormat(" WITH(NOLOCK)");
-
+
if (!string.IsNullOrEmpty(condition))
sb.AppendFormat(" ON {0}", condition);
-
- _join = string.IsNullOrEmpty(_join) ? sb.ToString() : string.Format("{0} {1}", _join, sb.ToString()); // No comma in this case
+
+ _join = string.IsNullOrEmpty(_join)
+ ? sb.ToString()
+ : string.Format("{0} {1}", _join, sb.ToString()); // No comma in this case
}
}
}
-
+
return this;
}
-
+
#endregion From/Join
-
+
#region Where
-
+
///
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
@@ -10273,7 +10751,7 @@ namespace DynamORM
{
return this.InternalWhere(func);
}
-
+
/// Add where condition.
/// Condition column with operator and value.
/// Builder instance.
@@ -10281,17 +10759,18 @@ namespace DynamORM
{
return this.InternalWhere(column);
}
-
+
/// Add where condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
- public virtual IDynamicSelectQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value)
+ public virtual IDynamicSelectQueryBuilder Where(string column, DynamicColumn.CompareOperator op,
+ object value)
{
return this.InternalWhere(column, op, value);
}
-
+
/// Add where condition.
/// Condition column.
/// Condition value.
@@ -10300,7 +10779,7 @@ namespace DynamORM
{
return this.InternalWhere(column, value);
}
-
+
/// Add where condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
@@ -10310,11 +10789,11 @@ namespace DynamORM
{
return this.InternalWhere(conditions, schema);
}
-
+
#endregion Where
-
+
#region Select
-
+
///
/// Adds to the 'Select' clause the contents obtained by parsing the dynamic lambda expressions given. The supported
/// formats are:
@@ -10327,45 +10806,46 @@ namespace DynamORM
/// The specification.
/// The specification.
/// This instance to permit chaining.
- public virtual IDynamicSelectQueryBuilder Select(Func fn, params Func[] func)
+ public virtual IDynamicSelectQueryBuilder Select(Func fn,
+ params Func[] func)
{
if (fn == null)
throw new ArgumentNullException("Array of specifications cannot be null.");
-
+
int index = SelectFunc(-1, fn);
if (func != null)
foreach (Func f in func)
index = SelectFunc(index, f);
-
+
return this;
}
-
+
private int SelectFunc(int index, Func f)
{
index++;
if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
-
+
using (DynamicParser parser = DynamicParser.Parse(f))
{
object result = parser.Result;
if (result == null)
throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
-
+
string main = null;
string alias = null;
bool all = false;
bool anon = false;
-
+
// If the expression resolves to a string...
if (result is string)
{
string node = (string)result;
Tuple tuple = node.SplitSomethingAndAlias();
main = tuple.Item1.Validated("Table and/or Column");
-
+
main = FixObjectName(main);
-
+
alias = tuple.Item2.Validated("Alias", canbeNull: true);
}
else if (result is DynamicParser.Node)
@@ -10376,7 +10856,7 @@ namespace DynamORM
else if (result.GetType().IsAnonymous())
{
anon = true;
-
+
foreach (KeyValuePair prop in result.ToDictionary())
{
if (prop.Value is string)
@@ -10384,7 +10864,7 @@ namespace DynamORM
string node = (string)prop.Value;
Tuple tuple = node.SplitSomethingAndAlias();
main = FixObjectName(tuple.Item1.Validated("Table and/or Column"));
-
+
////alias = tuple.Item2.Validated("Alias", canbeNull: true);
}
else if (prop.Value is DynamicParser.Node)
@@ -10395,9 +10875,10 @@ namespace DynamORM
else
{
// Or it is a not supported expression...
- throw new ArgumentException(string.Format("Specification #{0} in anonymous type is invalid: {1}", index, prop.Value));
+ throw new ArgumentException(string.Format(
+ "Specification #{0} in anonymous type is invalid: {1}", index, prop.Value));
}
-
+
alias = Database.DecorateName(prop.Key);
ParseSelectAddColumn(main, alias, all);
}
@@ -10405,16 +10886,17 @@ namespace DynamORM
else
{
// Or it is a not supported expression...
- throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index, result));
+ throw new ArgumentException(string.Format("Specification #{0} is invalid: {1}", index,
+ result));
}
-
+
if (!anon)
ParseSelectAddColumn(main, alias, all);
}
-
+
return index;
}
-
+
/// Add select columns.
/// Columns to add to object.
/// Builder instance.
@@ -10422,10 +10904,10 @@ namespace DynamORM
{
foreach (DynamicColumn col in columns)
Select(x => col.ToSQLSelectColumn(Database));
-
+
return this;
}
-
+
/// Add select columns.
/// Columns to add to object.
/// Column format consist of Column Name, Alias and
@@ -10436,66 +10918,67 @@ namespace DynamORM
DynamicColumn[] cols = new DynamicColumn[columns.Length];
for (int i = 0; i < columns.Length; i++)
cols[i] = DynamicColumn.ParseSelectColumn(columns[i]);
-
+
return SelectColumn(cols);
}
-
+
#endregion Select
-
+
#region GroupBy
-
+
///
/// Adds to the 'Group By' clause the contents obtained from from parsing the dynamic lambda expression given.
///
/// The specification.
/// The specification.
/// This instance to permit chaining.
- public virtual IDynamicSelectQueryBuilder GroupBy(Func fn, params Func[] func)
+ public virtual IDynamicSelectQueryBuilder GroupBy(Func fn,
+ params Func[] func)
{
if (fn == null)
throw new ArgumentNullException("Array of specifications cannot be null.");
-
+
int index = GroupByFunc(-1, fn);
-
+
if (func != null)
for (int i = 0; i < func.Length; i++)
{
Func f = func[i];
index = GroupByFunc(index, f);
}
-
+
return this;
}
-
+
private int GroupByFunc(int index, Func f)
{
index++;
if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
-
+
using (DynamicParser parser = DynamicParser.Parse(f))
{
object result = parser.Result;
if (result == null)
throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
-
+
string main = null;
-
+
if (result is string)
main = FixObjectName(result as string);
else
main = Parse(result, pars: Parameters);
-
+
main = main.Validated("Group By");
if (_groupby == null)
_groupby = main;
else
_groupby = string.Format("{0}, {1}", _groupby, main);
}
-
+
return index;
}
-
+
/// Add select columns.
/// Columns to group by.
/// Builder instance.
@@ -10506,10 +10989,10 @@ namespace DynamORM
DynamicColumn col = columns[i];
GroupBy(x => col.ToSQLGroupByColumn(Database));
}
-
+
return this;
}
-
+
/// Add select columns.
/// Columns to group by.
/// Column format consist of Column Name and
@@ -10519,11 +11002,11 @@ namespace DynamORM
{
return GroupByColumn(columns.Select(c => DynamicColumn.ParseSelectColumn(c)).ToArray());
}
-
+
#endregion GroupBy
-
+
#region Having
-
+
///
/// Adds to the 'Having' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, Having the specific customs virtual methods supported by the parser are used
@@ -10538,7 +11021,7 @@ namespace DynamORM
{
return this.InternalHaving(func);
}
-
+
/// Add Having condition.
/// Condition column with operator and value.
/// Builder instance.
@@ -10546,17 +11029,18 @@ namespace DynamORM
{
return this.InternalHaving(column);
}
-
+
/// Add Having condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
- public virtual IDynamicSelectQueryBuilder Having(string column, DynamicColumn.CompareOperator op, object value)
+ public virtual IDynamicSelectQueryBuilder Having(string column, DynamicColumn.CompareOperator op,
+ object value)
{
return this.InternalHaving(column, op, value);
}
-
+
/// Add Having condition.
/// Condition column.
/// Condition value.
@@ -10565,7 +11049,7 @@ namespace DynamORM
{
return this.InternalHaving(column, value);
}
-
+
/// Add Having condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
@@ -10575,11 +11059,11 @@ namespace DynamORM
{
return this.InternalHaving(conditions, schema);
}
-
+
#endregion Having
-
+
#region OrderBy
-
+
///
/// Adds to the 'Order By' clause the contents obtained from from parsing the dynamic lambda expression given. It
/// accepts a multipart column specification followed by an optional Ascending() or Descending() virtual methods
@@ -10589,49 +11073,52 @@ namespace DynamORM
/// The specification.
/// The specification.
/// This instance to permit chaining.
- public virtual IDynamicSelectQueryBuilder OrderBy(Func fn, params Func[] func)
+ public virtual IDynamicSelectQueryBuilder OrderBy(Func fn,
+ params Func[] func)
{
if (fn == null)
throw new ArgumentNullException("Array of specifications cannot be null.");
-
+
int index = OrderByFunc(-1, fn);
-
+
if (func != null)
for (int i = 0; i < func.Length; i++)
{
Func f = func[i];
index = OrderByFunc(index, f);
}
-
+
return this;
}
-
+
private int OrderByFunc(int index, Func f)
{
index++;
if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
-
+
using (DynamicParser parser = DynamicParser.Parse(f))
{
object result = parser.Result;
- if (result == null) throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
-
+ if (result == null)
+ throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
+
string main = null;
bool ascending = true;
-
+
if (result is int)
main = result.ToString();
else if (result is string)
{
string[] parts = ((string)result).Split(' ');
main = Database.StripName(parts.First());
-
+
int colNo;
if (!Int32.TryParse(main, out colNo))
main = FixObjectName(main);
-
- ascending = parts.Length != 2 || parts.Last().ToUpper() == "ASCENDING" || parts.Last().ToUpper() == "ASC";
+
+ ascending = parts.Length != 2 || parts.Last().ToUpper() == "ASCENDING" ||
+ parts.Last().ToUpper() == "ASC";
}
else
{
@@ -10644,12 +11131,17 @@ namespace DynamORM
{
object[] args = node.Arguments;
if (args != null && !(node.Host is DynamicParser.Node.Argument))
- throw new ArgumentException(string.Format("{0} must be a parameterless method, but found: {1}.", name, args.Sketch()));
- else if ((args == null || args.Length != 1) && node.Host is DynamicParser.Node.Argument)
- throw new ArgumentException(string.Format("{0} requires one numeric parameter, but found: {1}.", name, args.Sketch()));
-
+ throw new ArgumentException(string.Format(
+ "{0} must be a parameterless method, but found: {1}.", name,
+ args.Sketch()));
+ else if ((args == null || args.Length != 1) &&
+ node.Host is DynamicParser.Node.Argument)
+ throw new ArgumentException(string.Format(
+ "{0} requires one numeric parameter, but found: {1}.", name,
+ args.Sketch()));
+
ascending = (name == "ASCENDING" || name == "ASC") ? true : false;
-
+
if (args != null && args.Length == 1)
{
int col = -1;
@@ -10665,28 +11157,28 @@ namespace DynamORM
else
main = Parse(args[0], pars: Parameters);
}
-
+
result = node.Host;
}
}
-
+
// Just parsing the contents...
if (!(result is DynamicParser.Node.Argument))
main = Parse(result, pars: Parameters);
}
-
+
main = main.Validated("Order By");
main = string.Format("{0} {1}", main, ascending ? "ASC" : "DESC");
-
+
if (_orderby == null)
_orderby = main;
else
_orderby = string.Format("{0}, {1}", _orderby, main);
}
-
+
return index;
}
-
+
/// Add select columns.
/// Columns to order by.
/// Builder instance.
@@ -10697,10 +11189,10 @@ namespace DynamORM
DynamicColumn col = columns[i];
OrderBy(x => col.ToSQLOrderByColumn(Database));
}
-
+
return this;
}
-
+
/// Add select columns.
/// Columns to order by.
/// Column format consist of Column Name and
@@ -10710,11 +11202,11 @@ namespace DynamORM
{
return OrderByColumn(columns.Select(c => DynamicColumn.ParseOrderByColumn(c)).ToArray());
}
-
+
#endregion OrderBy
-
+
#region Top/Limit/Offset/Distinct
-
+
/// Set top if database support it.
/// How many objects select.
/// Builder instance.
@@ -10722,34 +11214,38 @@ namespace DynamORM
{
return Limit(top);
}
-
+
/// Set top if database support it.
/// How many objects select.
/// Builder instance.
public virtual IDynamicSelectQueryBuilder Limit(int? limit)
{
- if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset &&
- (Database.Options & DynamicDatabaseOptions.SupportFirstSkip) != DynamicDatabaseOptions.SupportFirstSkip &&
+ 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.");
-
+
_limit = limit;
return this;
}
-
+
/// Set top if database support it.
/// How many objects skip selecting.
/// Builder instance.
public virtual IDynamicSelectQueryBuilder Offset(int? offset)
{
- if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) != DynamicDatabaseOptions.SupportLimitOffset &&
- (Database.Options & DynamicDatabaseOptions.SupportFirstSkip) != DynamicDatabaseOptions.SupportFirstSkip)
+ if ((Database.Options & DynamicDatabaseOptions.SupportLimitOffset) !=
+ DynamicDatabaseOptions.SupportLimitOffset &&
+ (Database.Options & DynamicDatabaseOptions.SupportFirstSkip) !=
+ DynamicDatabaseOptions.SupportFirstSkip)
throw new NotSupportedException("Database doesn't support OFFSET clause.");
-
+
_offset = offset;
return this;
}
-
+
/// Set distinct mode.
/// Distinct mode.
/// Builder instance.
@@ -10758,92 +11254,99 @@ namespace DynamORM
_distinct = distinct;
return this;
}
-
+
#endregion Top/Limit/Offset/Distinct
-
+
#region Helpers
-
+
private void ParseSelectAddColumn(string main, string alias, bool all)
{
// We annotate the aliases being conservative...
main = main.Validated("Main");
-
+
////if (alias != null && !main.ContainsAny(StringExtensions.InvalidMemberChars)) TableAliasList.Add(new KTableAlias(main, alias));
-
+
// If all columns are requested...
if (all)
main += ".*";
-
+
// We finally add the contents...
string str = (alias == null || all) ? main : string.Format("{0} AS {1}", main, alias);
_select = _select == null ? str : string.Format("{0}, {1}", _select, str);
}
-
+
private void ParseSelectNode(object result, ref string column, ref string alias, ref bool all)
{
string main = null;
-
+
DynamicParser.Node node = (DynamicParser.Node)result;
while (true)
{
// Support for the AS() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "AS")
{
if (alias != null)
- throw new ArgumentException(string.Format("Alias '{0}' is already set when parsing '{1}'.", alias, result));
-
+ throw new ArgumentException(
+ string.Format("Alias '{0}' is already set when parsing '{1}'.", alias, result));
+
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args == null)
throw new ArgumentNullException("arg", "AS() is not a parameterless method.");
-
+
if (args.Length != 1)
- throw new ArgumentException("AS() requires one and only one parameter: " + args.Sketch());
-
+ throw new ArgumentException(
+ "AS() requires one and only one parameter: " + args.Sketch());
+
// Yes, we decorate columns
alias = Parse(args[0], rawstr: true, decorate: true, isMultiPart: false).Validated("Alias");
-
+
node = node.Host;
continue;
}
-
+
// Support for the ALL() virtual method...
- if (node is DynamicParser.Node.Method && ((DynamicParser.Node.Method)node).Name.ToUpper() == "ALL")
+ if (node is DynamicParser.Node.Method &&
+ ((DynamicParser.Node.Method)node).Name.ToUpper() == "ALL")
{
if (all)
- throw new ArgumentException(string.Format("Flag to select all columns is already set when parsing '{0}'.", result));
-
+ throw new ArgumentException(string.Format(
+ "Flag to select all columns is already set when parsing '{0}'.", result));
+
object[] args = ((DynamicParser.Node.Method)node).Arguments;
-
+
if (args != null)
- throw new ArgumentException("ALL() must be a parameterless virtual method, but found: " + args.Sketch());
-
+ throw new ArgumentException(
+ "ALL() must be a parameterless virtual method, but found: " + args.Sketch());
+
all = true;
-
+
node = node.Host;
continue;
}
-
+
// Support for table and/or column specifications...
if (node is DynamicParser.Node.GetMember)
{
if (main != null)
- throw new ArgumentException(string.Format("Main '{0}' is already set when parsing '{1}'.", main, result));
-
+ throw new ArgumentException(
+ string.Format("Main '{0}' is already set when parsing '{1}'.", main, result));
+
main = ((DynamicParser.Node.GetMember)node).Name;
-
+
if (node.Host is DynamicParser.Node.GetMember)
{
// If leaf then decorate
main = Database.DecorateName(main);
-
+
// Supporting multipart specifications...
node = node.Host;
-
+
// Get table/alias name
string table = ((DynamicParser.Node.GetMember)node).Name;
bool isAlias = node.Host is DynamicParser.Node.Argument && IsTableAlias(table);
-
+
if (isAlias)
main = string.Format("{0}.{1}", table, main);
else if (node.Host is DynamicParser.Node.GetMember)
@@ -10859,7 +11362,7 @@ namespace DynamORM
else if (node.Host is DynamicParser.Node.Argument)
{
string table = ((DynamicParser.Node.Argument)node.Host).Name;
-
+
if (IsTableAlias(table))
main = string.Format("{0}.{1}", table, Database.DecorateName(main));
else if (!IsTableAlias(main))
@@ -10867,74 +11370,78 @@ namespace DynamORM
}
else if (!(node.Host is DynamicParser.Node.Argument && IsTableAlias(main)))
main = Database.DecorateName(main);
-
+
node = node.Host;
-
+
continue;
}
-
+
// Support for generic sources...
if (node is DynamicParser.Node.Invoke)
{
if (main != null)
- throw new ArgumentException(string.Format("Main '{0}' is already set when parsing '{1}'.", main, result));
-
+ throw new ArgumentException(
+ string.Format("Main '{0}' is already set when parsing '{1}'.", main, result));
+
main = string.Format("{0}", Parse(node, rawstr: true, pars: Parameters));
-
+
node = node.Host;
continue;
}
-
+
// Just finished the parsing...
if (node is DynamicParser.Node.Argument)
{
if (string.IsNullOrEmpty(main) && IsTableAlias(node.Name))
main = node.Name;
-
+
break;
}
-
+
// All others are assumed to be part of the main element...
- if (main != null) throw new ArgumentException(string.Format("Main '{0}' is already set when parsing '{1}'.", main, result));
+ if (main != null)
+ throw new ArgumentException(string.Format("Main '{0}' is already set when parsing '{1}'.",
+ main, result));
main = Parse(node, pars: Parameters);
-
+
break;
}
-
+
column = main;
}
-
+
#endregion Helpers
-
+
#region IExtendedDisposable
-
+
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
public override void Dispose()
{
base.Dispose();
-
+
_select = _from = _join = _groupby = _orderby = null;
}
-
+
#endregion IExtendedDisposable
}
-
+
/// Update query builder.
- internal class DynamicUpdateQueryBuilder : DynamicModifyBuilder, IDynamicUpdateQueryBuilder, DynamicQueryBuilder.IQueryWithWhere
+ internal class DynamicUpdateQueryBuilder : DynamicModifyBuilder, IDynamicUpdateQueryBuilder,
+ DynamicQueryBuilder.IQueryWithWhere
{
private string _columns;
-
+
internal DynamicUpdateQueryBuilder(DynamicDatabase db)
: base(db)
{
}
-
+
public DynamicUpdateQueryBuilder(DynamicDatabase db, string tableName)
: base(db, tableName)
{
}
-
+
/// Generates the text this command will execute against the underlying database.
/// The text to execute against the underlying database.
/// This method must be override by derived classes.
@@ -10942,14 +11449,16 @@ namespace DynamORM
{
ITableInfo info = Tables.Single();
return string.Format("UPDATE {0}{1} SET {2}{3}{4}",
- string.IsNullOrEmpty(info.Owner) ? string.Empty : string.Format("{0}.", Database.DecorateName(info.Owner)),
+ string.IsNullOrEmpty(info.Owner)
+ ? string.Empty
+ : string.Format("{0}.", Database.DecorateName(info.Owner)),
Database.DecorateName(info.Name), _columns,
string.IsNullOrEmpty(WhereCondition) ? string.Empty : " WHERE ",
WhereCondition);
}
-
+
#region Update
-
+
/// Add update value or where condition using schema.
/// Update or where column name.
/// Column value.
@@ -10957,18 +11466,19 @@ namespace DynamORM
public virtual IDynamicUpdateQueryBuilder Update(string column, object value)
{
DynamicSchemaColumn? col = GetColumnFromSchema(column);
-
+
if (!col.HasValue && SupportSchema)
- throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", column));
-
+ throw new InvalidOperationException(
+ string.Format("Column '{0}' not found in schema, can't use universal approach.", column));
+
if (col.HasValue && col.Value.IsKey)
Where(column, value);
else
Values(column, value);
-
+
return this;
}
-
+
/// Add update values and where condition columns using schema.
/// Set values or conditions as properties and values of an object.
/// Builder instance.
@@ -10977,58 +11487,61 @@ namespace DynamORM
if (conditions is DynamicColumn)
{
DynamicColumn column = (DynamicColumn)conditions;
-
+
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
-
+
if (!col.HasValue && SupportSchema)
- throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", column));
-
+ throw new InvalidOperationException(
+ string.Format("Column '{0}' not found in schema, can't use universal approach.",
+ column));
+
if (col.HasValue && col.Value.IsKey)
Where(column);
else
Values(column.ColumnName, column.Value);
-
+
return this;
}
-
+
IDictionary dict = conditions.ToDictionary();
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(conditions.GetType());
-
+
foreach (KeyValuePair con in dict)
{
if (mapper.Ignored.Contains(con.Key))
continue;
-
+
string colName = mapper != null ? mapper.PropertyMap.TryGetValue(con.Key) ?? con.Key : con.Key;
DynamicSchemaColumn? col = GetColumnFromSchema(colName);
-
+
if (!col.HasValue && SupportSchema)
- throw new InvalidOperationException(string.Format("Column '{0}' not found in schema, can't use universal approach.", colName));
-
+ throw new InvalidOperationException(string.Format(
+ "Column '{0}' not found in schema, can't use universal approach.", colName));
+
if (col.HasValue)
{
colName = col.Value.Name;
-
+
if (col.Value.IsKey)
{
Where(colName, con.Value);
-
+
continue;
}
}
-
+
DynamicPropertyInvoker propMap = mapper.ColumnsMap.TryGetValue(colName.ToLower());
if (propMap == null || propMap.Column == null || !propMap.Column.IsNoUpdate)
Values(colName, con.Value);
}
-
+
return this;
}
-
+
#endregion Update
-
+
#region Values
-
+
///
/// Specifies the columns to update using the dynamic lambda expressions given. Each expression correspond to one
/// column, and can:
@@ -11041,36 +11554,37 @@ namespace DynamORM
{
if (func == null)
throw new ArgumentNullException("Array of specifications cannot be null.");
-
+
int index = -1;
foreach (Func f in func)
{
index++;
if (f == null)
throw new ArgumentNullException(string.Format("Specification #{0} cannot be null.", index));
-
+
object result = null;
-
+
using (DynamicParser p = DynamicParser.Parse(f))
{
result = p.Result;
-
+
if (result == null)
- throw new ArgumentException(string.Format("Specification #{0} resolves to null.", index));
-
+ throw new ArgumentException(
+ string.Format("Specification #{0} resolves to null.", index));
+
string main = null;
string value = null;
string str = null;
-
+
// When 'x => x.Table.Column = value' or 'x => x.Column = value'...
if (result is DynamicParser.Node.SetMember)
{
DynamicParser.Node.SetMember node = (DynamicParser.Node.SetMember)result;
-
+
DynamicSchemaColumn? col = GetColumnFromSchema(node.Name);
main = Database.DecorateName(node.Name);
value = Parse(node.Value, ref col, pars: Parameters, nulls: true);
-
+
str = string.Format("{0} = {1}", main, value);
_columns = _columns == null ? str : string.Format("{0}, {1}", _columns, str);
continue;
@@ -11080,7 +11594,7 @@ namespace DynamORM
Values(result);
continue;
}
-
+
// Other specifications are considered invalid...
string err = string.Format("Specification '{0}' is invalid.", result);
str = Parse(result);
@@ -11088,10 +11602,10 @@ namespace DynamORM
throw new ArgumentException(err);
}
}
-
+
return this;
}
-
+
/// Add insert fields.
/// Insert column.
/// Insert value.
@@ -11101,20 +11615,20 @@ namespace DynamORM
if (value is DynamicColumn)
{
DynamicColumn v = (DynamicColumn)value;
-
+
if (string.IsNullOrEmpty(v.ColumnName))
v.ColumnName = column;
-
+
return Values(v);
}
-
+
return Values(new DynamicColumn
{
ColumnName = column,
Value = value,
});
}
-
+
/// Add insert fields.
/// Set insert value as properties and values of an object.
/// Builder instance.
@@ -11124,19 +11638,19 @@ namespace DynamORM
{
DynamicColumn column = (DynamicColumn)o;
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
-
+
string main = FixObjectName(column.ColumnName, onlyColumn: true);
string value = Parse(column.Value, ref col, pars: Parameters, nulls: true);
-
+
string str = string.Format("{0} = {1}", main, value);
_columns = _columns == null ? str : string.Format("{0}, {1}", _columns, str);
-
+
return this;
}
-
+
IDictionary dict = o.ToDictionary();
DynamicTypeMap mapper = DynamicMapperCache.GetMapper(o.GetType());
-
+
if (mapper != null)
{
foreach (KeyValuePair con in dict)
@@ -11146,14 +11660,14 @@ namespace DynamORM
else
foreach (KeyValuePair con in dict)
Values(con.Key, con.Value);
-
+
return this;
}
-
+
#endregion Values
-
+
#region Where
-
+
///
/// Adds to the 'Where' clause the contents obtained from parsing the dynamic lambda expression given. The condition
/// is parsed to the appropriate syntax, where the specific customs virtual methods supported by the parser are used
@@ -11168,7 +11682,7 @@ namespace DynamORM
{
return this.InternalWhere(func);
}
-
+
/// Add where condition.
/// Condition column with operator and value.
/// Builder instance.
@@ -11176,17 +11690,18 @@ namespace DynamORM
{
return this.InternalWhere(column);
}
-
+
/// Add where condition.
/// Condition column.
/// Condition operator.
/// Condition value.
/// Builder instance.
- public virtual IDynamicUpdateQueryBuilder Where(string column, DynamicColumn.CompareOperator op, object value)
+ public virtual IDynamicUpdateQueryBuilder Where(string column, DynamicColumn.CompareOperator op,
+ object value)
{
return this.InternalWhere(column, op, value);
}
-
+
/// Add where condition.
/// Condition column.
/// Condition value.
@@ -11195,7 +11710,7 @@ namespace DynamORM
{
return this.InternalWhere(column, value);
}
-
+
/// Add where condition.
/// Set conditions as properties and values of an object.
/// If true use schema to determine key columns and ignore those which
@@ -11205,27 +11720,27 @@ namespace DynamORM
{
return this.InternalWhere(conditions, schema);
}
-
+
#endregion Where
-
+
#region IExtendedDisposable
-
+
/// Performs application-defined tasks associated with
/// freeing, releasing, or resetting unmanaged resources.
public override void Dispose()
{
base.Dispose();
-
+
_columns = null;
}
-
+
#endregion IExtendedDisposable
}
}
}
namespace Helpers
- {
+ {
/// Defines methods to support the comparison of collections for equality.
/// The type of collection to compare.
public class CollectionComparer : IEqualityComparer>
@@ -11238,7 +11753,7 @@ namespace DynamORM
{
return Equals(first, second);
}
-
+
///