This commit is contained in:
13
DynamORM.sln
13
DynamORM.sln
@@ -1,11 +1,12 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
# SharpDevelop 4.2.2.8818
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM", "DynamORM\DynamORM.csproj", "{63963ED7-9C78-4672-A4D4-339B6E825503}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM.Tests", "DynamORM.Tests\DynamORM.Tests.csproj", "{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AmalgamationTool", "AmalgamationTool\AmalgamationTool.csproj", "{A64D2052-D0CD-488E-BF05-E5952615D926}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -36,6 +37,16 @@ Global
|
||||
{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Debug|x86.Build.0 = Debug|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Release|Any CPU.ActiveCfg = Release|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Release|x86.ActiveCfg = Release|x86
|
||||
{A64D2052-D0CD-488E-BF05-E5952615D926}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -48,11 +48,6 @@ namespace DynamORM.Builders
|
||||
/// <returns>This instance to permit chaining.</returns>
|
||||
IDynamicInsertQueryBuilder Insert(params Func<dynamic, object>[] func);
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column and value.</param>
|
||||
/// <returns>Builder instance.</returns>
|
||||
IDynamicInsertQueryBuilder Insert(DynamicColumn column);
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column.</param>
|
||||
/// <param name="value">Insert value.</param>
|
||||
|
||||
@@ -70,20 +70,5 @@ namespace DynamORM.Builders
|
||||
/// <summary>Gets or sets the on create real parameter action.</summary>
|
||||
/// <remarks>This is exposed to allow modification of parameter.</remarks>
|
||||
Action<IParameter, IDbDataParameter> OnCreateParameter { get; set; }
|
||||
|
||||
/// <summary>Creates sub query.</summary>
|
||||
/// <returns>Sub query builder.</returns>
|
||||
IDynamicSelectQueryBuilder SubQuery();
|
||||
|
||||
/// <summary>Adds to the 'From' clause of sub query the contents obtained by
|
||||
/// parsing the dynamic lambda expressions given. The supported formats are:
|
||||
/// <para>- Resolve to a string: 'x => "Table AS Alias', where the alias part is optional.</para>
|
||||
/// <para>- Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional.</para>
|
||||
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this
|
||||
/// case the alias is not annotated.</para>
|
||||
/// </summary>
|
||||
/// <param name="func">The specification.</param>
|
||||
/// <returns>This instance to permit chaining.</returns>
|
||||
IDynamicSelectQueryBuilder SubQuery(params Func<dynamic, object>[] func);
|
||||
}
|
||||
}
|
||||
@@ -40,11 +40,6 @@ namespace DynamORM.Builders
|
||||
|
||||
#region Update
|
||||
|
||||
/// <summary>Add update value or where condition using schema.</summary>
|
||||
/// <param name="column">Update or where column name and value.</param>
|
||||
/// <returns>Builder instance.</returns>
|
||||
IDynamicUpdateQueryBuilder Update(DynamicColumn column);
|
||||
|
||||
/// <summary>Add update value or where condition using schema.</summary>
|
||||
/// <param name="column">Update or where column name.</param>
|
||||
/// <param name="value">Column value.</param>
|
||||
@@ -70,11 +65,6 @@ namespace DynamORM.Builders
|
||||
/// <returns>This instance to permit chaining.</returns>
|
||||
IDynamicUpdateQueryBuilder Values(params Func<dynamic, object>[] func);
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column and value.</param>
|
||||
/// <returns>Builder instance.</returns>
|
||||
IDynamicUpdateQueryBuilder Values(DynamicColumn column);
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column.</param>
|
||||
/// <param name="value">Insert value.</param>
|
||||
|
||||
@@ -136,22 +136,6 @@ namespace DynamORM.Builders.Implementation
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column and value.</param>
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicInsertQueryBuilder Insert(DynamicColumn column)
|
||||
{
|
||||
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
|
||||
|
||||
string main = FixObjectName(column.ColumnName, onlyColumn: true);
|
||||
string value = Parse(column.Value, pars: Parameters, nulls: true, columnSchema: col);
|
||||
|
||||
_columns = _columns == null ? main : string.Format("{0}, {1}", _columns, main);
|
||||
_values = _values == null ? value : string.Format("{0}, {1}", _values, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column.</param>
|
||||
/// <param name="value">Insert value.</param>
|
||||
@@ -180,6 +164,20 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicInsertQueryBuilder Insert(object o)
|
||||
{
|
||||
if (o is DynamicColumn)
|
||||
{
|
||||
var column = (DynamicColumn)o;
|
||||
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
|
||||
|
||||
string main = FixObjectName(column.ColumnName, onlyColumn: true);
|
||||
string value = Parse(column.Value, pars: Parameters, nulls: true, columnSchema: col);
|
||||
|
||||
_columns = _columns == null ? main : string.Format("{0}, {1}", _columns, main);
|
||||
_values = _values == null ? value : string.Format("{0}, {1}", _values, value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
var dict = o.ToDictionary();
|
||||
var mapper = DynamicMapperCache.GetMapper(o.GetType());
|
||||
|
||||
|
||||
@@ -269,31 +269,6 @@ namespace DynamORM.Builders.Implementation
|
||||
}));
|
||||
}
|
||||
|
||||
#region SubQuery
|
||||
|
||||
/// <summary>Creates sub query.</summary>
|
||||
/// <returns>Sub query builder.</returns>
|
||||
public IDynamicSelectQueryBuilder SubQuery()
|
||||
{
|
||||
return new DynamicSelectQueryBuilder(Database, this);
|
||||
}
|
||||
|
||||
/// <summary>Adds to the 'From' clause of sub query the contents obtained by
|
||||
/// parsing the dynamic lambda expressions given. The supported formats are:
|
||||
/// <para>- Resolve to a string: 'x => "Table AS Alias', where the alias part is optional.</para>
|
||||
/// <para>- Resolve to an expression: 'x => x.Table.As( x.Alias )', where the alias part is optional.</para>
|
||||
/// <para>- Generic expression: 'x => x( expression ).As( x.Alias )', where the alias part is mandatory. In this
|
||||
/// case the alias is not annotated.</para>
|
||||
/// </summary>
|
||||
/// <param name="func">The specification.</param>
|
||||
/// <returns>This instance to permit chaining.</returns>
|
||||
public IDynamicSelectQueryBuilder SubQuery(params Func<dynamic, object>[] func)
|
||||
{
|
||||
return SubQuery().From(func);
|
||||
}
|
||||
|
||||
#endregion SubQuery
|
||||
|
||||
#endregion IDynamicQueryBuilder
|
||||
|
||||
#region Parser
|
||||
|
||||
@@ -67,24 +67,6 @@ namespace DynamORM.Builders.Implementation
|
||||
|
||||
#region Update
|
||||
|
||||
/// <summary>Add update value or where condition using schema.</summary>
|
||||
/// <param name="column">Update or where column name and value.</param>
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicUpdateQueryBuilder Update(DynamicColumn column)
|
||||
{
|
||||
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));
|
||||
|
||||
if (col.HasValue && col.Value.IsKey)
|
||||
Where(column);
|
||||
else
|
||||
Values(column.ColumnName, column.Value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>Add update value or where condition using schema.</summary>
|
||||
/// <param name="column">Update or where column name.</param>
|
||||
/// <param name="value">Column value.</param>
|
||||
@@ -110,7 +92,21 @@ namespace DynamORM.Builders.Implementation
|
||||
public virtual IDynamicUpdateQueryBuilder Update(object conditions)
|
||||
{
|
||||
if (conditions is DynamicColumn)
|
||||
return Update((DynamicColumn)conditions);
|
||||
{
|
||||
var 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));
|
||||
|
||||
if (col.HasValue && col.Value.IsKey)
|
||||
Where(column);
|
||||
else
|
||||
Values(column.ColumnName, column.Value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
var dict = conditions.ToDictionary();
|
||||
var mapper = DynamicMapperCache.GetMapper(conditions.GetType());
|
||||
@@ -205,22 +201,6 @@ namespace DynamORM.Builders.Implementation
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column and value.</param>
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicUpdateQueryBuilder Values(DynamicColumn column)
|
||||
{
|
||||
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
|
||||
|
||||
string main = FixObjectName(column.ColumnName, onlyColumn: true);
|
||||
string value = Parse(column.Value, pars: Parameters, nulls: true, columnSchema: col);
|
||||
|
||||
var str = string.Format("{0} = {1}", main, value);
|
||||
_columns = _columns == null ? str : string.Format("{0}, {1}", _columns, str);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>Add insert fields.</summary>
|
||||
/// <param name="column">Insert column.</param>
|
||||
/// <param name="value">Insert value.</param>
|
||||
@@ -249,6 +229,20 @@ namespace DynamORM.Builders.Implementation
|
||||
/// <returns>Builder instance.</returns>
|
||||
public virtual IDynamicUpdateQueryBuilder Values(object o)
|
||||
{
|
||||
if (o is DynamicColumn)
|
||||
{
|
||||
var column = (DynamicColumn)o;
|
||||
DynamicSchemaColumn? col = column.Schema ?? GetColumnFromSchema(column.ColumnName);
|
||||
|
||||
string main = FixObjectName(column.ColumnName, onlyColumn: true);
|
||||
string value = Parse(column.Value, pars: Parameters, nulls: true, columnSchema: col);
|
||||
|
||||
var str = string.Format("{0} = {1}", main, value);
|
||||
_columns = _columns == null ? str : string.Format("{0}, {1}", _columns, str);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
var dict = o.ToDictionary();
|
||||
var mapper = DynamicMapperCache.GetMapper(o.GetType());
|
||||
|
||||
|
||||
@@ -378,10 +378,10 @@ namespace DynamORM
|
||||
|
||||
affected = 0;
|
||||
|
||||
var exCmd = new StringBuilder();
|
||||
cmd.Dump(exCmd);
|
||||
var problematicCommand = new StringBuilder();
|
||||
cmd.Dump(problematicCommand);
|
||||
|
||||
throw new InvalidOperationException(exCmd.ToString(), ex);
|
||||
throw new InvalidOperationException(problematicCommand.ToString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -413,7 +413,7 @@ namespace DynamORM
|
||||
return new DynamicUpdateQueryBuilder(this).Table(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>Bulk update objects into database.</summary>
|
||||
/// <summary>Bulk update objects in database.</summary>
|
||||
/// <typeparam name="T">Type of objects to update.</typeparam>
|
||||
/// <param name="e">Enumerable containing instances of objects to update.</param>
|
||||
/// <returns>Number of updated rows.</returns>
|
||||
@@ -509,10 +509,192 @@ namespace DynamORM
|
||||
|
||||
affected = 0;
|
||||
|
||||
var exCmd = new StringBuilder();
|
||||
cmd.Dump(exCmd);
|
||||
var problematicCommand = new StringBuilder();
|
||||
cmd.Dump(problematicCommand);
|
||||
|
||||
throw new InvalidOperationException(exCmd.ToString(), ex);
|
||||
throw new InvalidOperationException(problematicCommand.ToString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
/// <summary>Bulk update or insert objects into database.</summary>
|
||||
/// <typeparam name="T">Type of objects to update or insert.</typeparam>
|
||||
/// <param name="e">Enumerable containing instances of objects to update or insert.</param>
|
||||
/// <returns>Number of updated or inserted rows.</returns>
|
||||
public virtual int UpdateOrInsert<T>(IEnumerable<T> e) where T : class
|
||||
{
|
||||
int affected = 0;
|
||||
var mapper = DynamicMapperCache.GetMapper(typeof(T));
|
||||
|
||||
if (mapper != null)
|
||||
{
|
||||
using (var con = Open())
|
||||
using (var tra = con.BeginTransaction())
|
||||
using (var cmdUp = con.CreateCommand())
|
||||
using (var cmdIn = con.CreateCommand())
|
||||
{
|
||||
try
|
||||
{
|
||||
#region Update
|
||||
|
||||
var parametersUp = new Dictionary<IDbDataParameter, DynamicPropertyInvoker>();
|
||||
|
||||
if (!string.IsNullOrEmpty(mapper.UpdateCommandText))
|
||||
{
|
||||
cmdUp.CommandText = mapper.UpdateCommandText;
|
||||
|
||||
foreach (var col in mapper.ColumnsMap.Values
|
||||
.Where(di => !di.Ignore && di.UpdateCommandParameter != null)
|
||||
.OrderBy(di => di.UpdateCommandParameter.Ordinal))
|
||||
{
|
||||
var para = cmdUp.CreateParameter();
|
||||
para.ParameterName = col.UpdateCommandParameter.Name;
|
||||
para.DbType = col.UpdateCommandParameter.Type;
|
||||
cmdUp.Parameters.Add(para);
|
||||
|
||||
parametersUp[para] = col;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicPropertyInvoker currentprop = null;
|
||||
var temp = new Dictionary<string, DynamicPropertyInvoker>();
|
||||
int ord = 0;
|
||||
|
||||
var ib = Update<T>()
|
||||
.SetVirtualMode(true)
|
||||
.CreateTemporaryParameterAction(p => temp[p.Name] = currentprop)
|
||||
.CreateParameterAction((p, cp) =>
|
||||
{
|
||||
parametersUp[cp] = temp[p.Name];
|
||||
parametersUp[cp].UpdateCommandParameter = new DynamicPropertyInvoker.ParameterSpec
|
||||
{
|
||||
Name = cp.ParameterName,
|
||||
Type = cp.DbType,
|
||||
Ordinal = ord++,
|
||||
};
|
||||
});
|
||||
|
||||
foreach (var prop in mapper.PropertyMap)
|
||||
if (!mapper.Ignored.Contains(prop.Key))
|
||||
{
|
||||
var col = mapper.PropertyMap.TryGetValue(prop.Key) ?? prop.Key;
|
||||
currentprop = mapper.ColumnsMap.TryGetValue(col.ToLower());
|
||||
|
||||
if (currentprop.Ignore)
|
||||
continue;
|
||||
|
||||
if (currentprop.Get != null)
|
||||
{
|
||||
if (currentprop.Column != null && currentprop.Column.IsKey)
|
||||
ib.Where(col, null);
|
||||
else
|
||||
ib.Values(col, null);
|
||||
}
|
||||
}
|
||||
|
||||
ib.FillCommand(cmdUp);
|
||||
|
||||
// Cache command
|
||||
mapper.UpdateCommandText = cmdUp.CommandText;
|
||||
}
|
||||
|
||||
#endregion Update
|
||||
|
||||
#region Insert
|
||||
|
||||
var parametersIn = new Dictionary<IDbDataParameter, DynamicPropertyInvoker>();
|
||||
|
||||
if (!string.IsNullOrEmpty(mapper.InsertCommandText))
|
||||
{
|
||||
cmdIn.CommandText = mapper.InsertCommandText;
|
||||
|
||||
foreach (var col in mapper.ColumnsMap.Values
|
||||
.Where(di => !di.Ignore && di.InsertCommandParameter != null)
|
||||
.OrderBy(di => di.InsertCommandParameter.Ordinal))
|
||||
{
|
||||
var para = cmdIn.CreateParameter();
|
||||
para.ParameterName = col.InsertCommandParameter.Name;
|
||||
para.DbType = col.InsertCommandParameter.Type;
|
||||
cmdIn.Parameters.Add(para);
|
||||
|
||||
parametersIn[para] = col;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicPropertyInvoker currentprop = null;
|
||||
var temp = new Dictionary<string, DynamicPropertyInvoker>();
|
||||
int ord = 0;
|
||||
|
||||
var ib = Insert<T>()
|
||||
.SetVirtualMode(true)
|
||||
.CreateTemporaryParameterAction(p => temp[p.Name] = currentprop)
|
||||
.CreateParameterAction((p, cp) =>
|
||||
{
|
||||
parametersIn[cp] = temp[p.Name];
|
||||
parametersIn[cp].InsertCommandParameter = new DynamicPropertyInvoker.ParameterSpec
|
||||
{
|
||||
Name = cp.ParameterName,
|
||||
Type = cp.DbType,
|
||||
Ordinal = ord++,
|
||||
};
|
||||
});
|
||||
|
||||
foreach (var prop in mapper.PropertyMap)
|
||||
if (!mapper.Ignored.Contains(prop.Key))
|
||||
{
|
||||
var col = mapper.PropertyMap.TryGetValue(prop.Key) ?? prop.Key;
|
||||
currentprop = mapper.ColumnsMap.TryGetValue(col.ToLower());
|
||||
|
||||
if (currentprop.Ignore)
|
||||
continue;
|
||||
|
||||
if (currentprop.Get != null)
|
||||
ib.Insert(col, null);
|
||||
}
|
||||
|
||||
ib.FillCommand(cmdIn);
|
||||
|
||||
// Cache command
|
||||
mapper.InsertCommandText = cmdIn.CommandText;
|
||||
}
|
||||
|
||||
#endregion Insert
|
||||
|
||||
foreach (var o in e)
|
||||
{
|
||||
foreach (var m in parametersUp)
|
||||
m.Key.Value = m.Value.Get(o);
|
||||
|
||||
int a = cmdUp.ExecuteNonQuery();
|
||||
if (a == 0)
|
||||
{
|
||||
foreach (var m in parametersIn)
|
||||
m.Key.Value = m.Value.Get(o);
|
||||
|
||||
a = cmdIn.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
affected += a;
|
||||
}
|
||||
|
||||
tra.Commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (tra != null)
|
||||
tra.Rollback();
|
||||
|
||||
affected = 0;
|
||||
|
||||
var problematicCommand = new StringBuilder();
|
||||
cmdUp.Dump(problematicCommand);
|
||||
|
||||
throw new InvalidOperationException(problematicCommand.ToString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -544,6 +726,111 @@ namespace DynamORM
|
||||
return new DynamicDeleteQueryBuilder(this).Table(typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>Bulk delete objects in database.</summary>
|
||||
/// <typeparam name="T">Type of objects to delete.</typeparam>
|
||||
/// <param name="e">Enumerable containing instances of objects to delete.</param>
|
||||
/// <returns>Number of deleted rows.</returns>
|
||||
public virtual int Delete<T>(IEnumerable<T> e) where T : class
|
||||
{
|
||||
int affected = 0;
|
||||
var mapper = DynamicMapperCache.GetMapper(typeof(T));
|
||||
|
||||
if (mapper != null)
|
||||
{
|
||||
using (var con = Open())
|
||||
using (var tra = con.BeginTransaction())
|
||||
using (var cmd = con.CreateCommand())
|
||||
{
|
||||
try
|
||||
{
|
||||
var parameters = new Dictionary<IDbDataParameter, DynamicPropertyInvoker>();
|
||||
|
||||
if (!string.IsNullOrEmpty(mapper.DeleteCommandText))
|
||||
{
|
||||
cmd.CommandText = mapper.DeleteCommandText;
|
||||
|
||||
foreach (var col in mapper.ColumnsMap.Values
|
||||
.Where(di => !di.Ignore && di.DeleteCommandParameter != null)
|
||||
.OrderBy(di => di.DeleteCommandParameter.Ordinal))
|
||||
{
|
||||
var para = cmd.CreateParameter();
|
||||
para.ParameterName = col.DeleteCommandParameter.Name;
|
||||
para.DbType = col.DeleteCommandParameter.Type;
|
||||
cmd.Parameters.Add(para);
|
||||
|
||||
parameters[para] = col;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DynamicPropertyInvoker currentprop = null;
|
||||
var temp = new Dictionary<string, DynamicPropertyInvoker>();
|
||||
int ord = 0;
|
||||
|
||||
var ib = Delete<T>()
|
||||
.SetVirtualMode(true)
|
||||
.CreateTemporaryParameterAction(p => temp[p.Name] = currentprop)
|
||||
.CreateParameterAction((p, cp) =>
|
||||
{
|
||||
parameters[cp] = temp[p.Name];
|
||||
parameters[cp].DeleteCommandParameter = new DynamicPropertyInvoker.ParameterSpec
|
||||
{
|
||||
Name = cp.ParameterName,
|
||||
Type = cp.DbType,
|
||||
Ordinal = ord++,
|
||||
};
|
||||
});
|
||||
|
||||
foreach (var prop in mapper.PropertyMap)
|
||||
if (!mapper.Ignored.Contains(prop.Key))
|
||||
{
|
||||
var col = mapper.PropertyMap.TryGetValue(prop.Key) ?? prop.Key;
|
||||
currentprop = mapper.ColumnsMap.TryGetValue(col.ToLower());
|
||||
|
||||
if (currentprop.Ignore)
|
||||
continue;
|
||||
|
||||
if (currentprop.Get != null)
|
||||
{
|
||||
if (currentprop.Column != null && currentprop.Column.IsKey)
|
||||
ib.Where(col, null);
|
||||
}
|
||||
}
|
||||
|
||||
ib.FillCommand(cmd);
|
||||
|
||||
// Cache command
|
||||
mapper.DeleteCommandText = cmd.CommandText;
|
||||
}
|
||||
|
||||
foreach (var o in e)
|
||||
{
|
||||
foreach (var m in parameters)
|
||||
m.Key.Value = m.Value.Get(o);
|
||||
|
||||
affected += cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
tra.Commit();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (tra != null)
|
||||
tra.Rollback();
|
||||
|
||||
affected = 0;
|
||||
|
||||
var problematicCommand = new StringBuilder();
|
||||
cmd.Dump(problematicCommand);
|
||||
|
||||
throw new InvalidOperationException(problematicCommand.ToString(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affected;
|
||||
}
|
||||
|
||||
#endregion From/Insert/Update/Delete
|
||||
|
||||
#region Schema
|
||||
|
||||
@@ -838,14 +838,25 @@ namespace DynamORM
|
||||
return b;
|
||||
}
|
||||
|
||||
/// <summary>Creates sub query that can be used inside of from/join/expresions.</summary>
|
||||
/// <summary>Creates sub query that can be used inside of from/join/expressions.</summary>
|
||||
/// <typeparam name="T">Class implementing <see cref="IDynamicQueryBuilder"/> interface.</typeparam>
|
||||
/// <param name="b">The builder that will be parent of new sub query.</param>
|
||||
/// <param name="subquery">First argument is parent query, second one is a subquery.</param>
|
||||
/// <param name="func">The specification for subquery.</param>
|
||||
/// <param name="func">The specification for sub query.</param>
|
||||
/// <returns>Instance of sub query.</returns>
|
||||
public static IDynamicSelectQueryBuilder SubQuery<T>(this T b, params Func<dynamic, object>[] func) where T : IDynamicQueryBuilder
|
||||
{
|
||||
return func == null || func.Length == 0 ? new DynamicSelectQueryBuilder(b.Database, b as DynamicQueryBuilder) : new DynamicSelectQueryBuilder(b.Database, b as DynamicQueryBuilder).From(func);
|
||||
}
|
||||
|
||||
/// <summary>Creates sub query that can be used inside of from/join/expressions.</summary>
|
||||
/// <typeparam name="T">Class implementing <see cref="IDynamicQueryBuilder"/> interface.</typeparam>
|
||||
/// <param name="b">The builder that will be parent of new sub query.</param>
|
||||
/// <param name="subquery">First argument is parent query, second one is a sub query.</param>
|
||||
/// <param name="func">The specification for sub query.</param>
|
||||
/// <returns>This instance to permit chaining.</returns>
|
||||
public static T SubQuery<T>(this T b, Action<T, IDynamicSelectQueryBuilder> subquery, params Func<dynamic, object>[] func) where T : IDynamicQueryBuilder
|
||||
{
|
||||
var sub = func == null || func.Length == 0 ? b.SubQuery() : b.SubQuery(func);
|
||||
var sub = b.SubQuery(func);
|
||||
|
||||
subquery(b, sub);
|
||||
|
||||
|
||||
@@ -122,6 +122,8 @@ namespace DynamORM.Mapper
|
||||
|
||||
internal ParameterSpec UpdateCommandParameter { get; set; }
|
||||
|
||||
internal ParameterSpec DeleteCommandParameter { get; set; }
|
||||
|
||||
#endregion Type command cache
|
||||
}
|
||||
}
|
||||
@@ -142,6 +142,8 @@ namespace DynamORM.Mapper
|
||||
|
||||
internal string UpdateCommandText { get; set; }
|
||||
|
||||
internal string DeleteCommandText { get; set; }
|
||||
|
||||
#endregion Type command cache
|
||||
}
|
||||
}
|
||||
@@ -64,4 +64,9 @@ using System.Runtime.InteropServices;
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.1.0.1")]
|
||||
[assembly: AssemblyFileVersion("1.1.0.1")]
|
||||
[assembly: InternalsVisibleTo("DynamORM.Tests")]
|
||||
[assembly: InternalsVisibleTo("DynamORM.Tests")]
|
||||
[assembly: Obfuscation(Feature = "encrypt symbol names with password #dr4cul4#", Exclude = false)]
|
||||
[assembly: Obfuscation(Feature = "code control flow obfuscation", Exclude = false)]
|
||||
[assembly: Obfuscation(Feature = "rename serializable symbols", Exclude = false)]
|
||||
[assembly: Obfuscation(Feature = "anonymous type properties renaming", Exclude = true)]
|
||||
[assembly: Obfuscation(Feature = "optimization", Exclude = true)]
|
||||
Reference in New Issue
Block a user