This commit is contained in:
13
DynamORM.sln
13
DynamORM.sln
@@ -1,11 +1,12 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
# Visual Studio 2010
|
# Visual Studio 2010
|
||||||
# SharpDevelop 4.2.2.8818
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM", "DynamORM\DynamORM.csproj", "{63963ED7-9C78-4672-A4D4-339B6E825503}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM", "DynamORM\DynamORM.csproj", "{63963ED7-9C78-4672-A4D4-339B6E825503}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM.Tests", "DynamORM.Tests\DynamORM.Tests.csproj", "{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynamORM.Tests", "DynamORM.Tests\DynamORM.Tests.csproj", "{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AmalgamationTool", "AmalgamationTool\AmalgamationTool.csproj", "{A64D2052-D0CD-488E-BF05-E5952615D926}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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.ActiveCfg = Release|Any CPU
|
||||||
{D5013B4E-8A1B-4DBB-8FB5-E09935F4F764}.Release|Mixed Platforms.Build.0 = 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
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -48,11 +48,6 @@ namespace DynamORM.Builders
|
|||||||
/// <returns>This instance to permit chaining.</returns>
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
IDynamicInsertQueryBuilder Insert(params Func<dynamic, object>[] func);
|
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>
|
/// <summary>Add insert fields.</summary>
|
||||||
/// <param name="column">Insert column.</param>
|
/// <param name="column">Insert column.</param>
|
||||||
/// <param name="value">Insert value.</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>
|
/// <summary>Gets or sets the on create real parameter action.</summary>
|
||||||
/// <remarks>This is exposed to allow modification of parameter.</remarks>
|
/// <remarks>This is exposed to allow modification of parameter.</remarks>
|
||||||
Action<IParameter, IDbDataParameter> OnCreateParameter { get; set; }
|
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
|
#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>
|
/// <summary>Add update value or where condition using schema.</summary>
|
||||||
/// <param name="column">Update or where column name.</param>
|
/// <param name="column">Update or where column name.</param>
|
||||||
/// <param name="value">Column value.</param>
|
/// <param name="value">Column value.</param>
|
||||||
@@ -70,11 +65,6 @@ namespace DynamORM.Builders
|
|||||||
/// <returns>This instance to permit chaining.</returns>
|
/// <returns>This instance to permit chaining.</returns>
|
||||||
IDynamicUpdateQueryBuilder Values(params Func<dynamic, object>[] func);
|
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>
|
/// <summary>Add insert fields.</summary>
|
||||||
/// <param name="column">Insert column.</param>
|
/// <param name="column">Insert column.</param>
|
||||||
/// <param name="value">Insert value.</param>
|
/// <param name="value">Insert value.</param>
|
||||||
|
|||||||
@@ -136,22 +136,6 @@ namespace DynamORM.Builders.Implementation
|
|||||||
return this;
|
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>
|
/// <summary>Add insert fields.</summary>
|
||||||
/// <param name="column">Insert column.</param>
|
/// <param name="column">Insert column.</param>
|
||||||
/// <param name="value">Insert value.</param>
|
/// <param name="value">Insert value.</param>
|
||||||
@@ -180,6 +164,20 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicInsertQueryBuilder Insert(object o)
|
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 dict = o.ToDictionary();
|
||||||
var mapper = DynamicMapperCache.GetMapper(o.GetType());
|
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
|
#endregion IDynamicQueryBuilder
|
||||||
|
|
||||||
#region Parser
|
#region Parser
|
||||||
|
|||||||
@@ -67,24 +67,6 @@ namespace DynamORM.Builders.Implementation
|
|||||||
|
|
||||||
#region Update
|
#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>
|
/// <summary>Add update value or where condition using schema.</summary>
|
||||||
/// <param name="column">Update or where column name.</param>
|
/// <param name="column">Update or where column name.</param>
|
||||||
/// <param name="value">Column value.</param>
|
/// <param name="value">Column value.</param>
|
||||||
@@ -110,7 +92,21 @@ namespace DynamORM.Builders.Implementation
|
|||||||
public virtual IDynamicUpdateQueryBuilder Update(object conditions)
|
public virtual IDynamicUpdateQueryBuilder Update(object conditions)
|
||||||
{
|
{
|
||||||
if (conditions is DynamicColumn)
|
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 dict = conditions.ToDictionary();
|
||||||
var mapper = DynamicMapperCache.GetMapper(conditions.GetType());
|
var mapper = DynamicMapperCache.GetMapper(conditions.GetType());
|
||||||
@@ -205,22 +201,6 @@ namespace DynamORM.Builders.Implementation
|
|||||||
return this;
|
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>
|
/// <summary>Add insert fields.</summary>
|
||||||
/// <param name="column">Insert column.</param>
|
/// <param name="column">Insert column.</param>
|
||||||
/// <param name="value">Insert value.</param>
|
/// <param name="value">Insert value.</param>
|
||||||
@@ -249,6 +229,20 @@ namespace DynamORM.Builders.Implementation
|
|||||||
/// <returns>Builder instance.</returns>
|
/// <returns>Builder instance.</returns>
|
||||||
public virtual IDynamicUpdateQueryBuilder Values(object o)
|
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 dict = o.ToDictionary();
|
||||||
var mapper = DynamicMapperCache.GetMapper(o.GetType());
|
var mapper = DynamicMapperCache.GetMapper(o.GetType());
|
||||||
|
|
||||||
|
|||||||
@@ -378,10 +378,10 @@ namespace DynamORM
|
|||||||
|
|
||||||
affected = 0;
|
affected = 0;
|
||||||
|
|
||||||
var exCmd = new StringBuilder();
|
var problematicCommand = new StringBuilder();
|
||||||
cmd.Dump(exCmd);
|
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));
|
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>
|
/// <typeparam name="T">Type of objects to update.</typeparam>
|
||||||
/// <param name="e">Enumerable containing instances of objects to update.</param>
|
/// <param name="e">Enumerable containing instances of objects to update.</param>
|
||||||
/// <returns>Number of updated rows.</returns>
|
/// <returns>Number of updated rows.</returns>
|
||||||
@@ -509,10 +509,192 @@ namespace DynamORM
|
|||||||
|
|
||||||
affected = 0;
|
affected = 0;
|
||||||
|
|
||||||
var exCmd = new StringBuilder();
|
var problematicCommand = new StringBuilder();
|
||||||
cmd.Dump(exCmd);
|
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));
|
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
|
#endregion From/Insert/Update/Delete
|
||||||
|
|
||||||
#region Schema
|
#region Schema
|
||||||
|
|||||||
@@ -838,14 +838,25 @@ namespace DynamORM
|
|||||||
return b;
|
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="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="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="subquery">First argument is parent query, second one is a sub query.</param>
|
||||||
/// <param name="func">The specification for sub query.</param>
|
/// <param name="func">The specification for sub query.</param>
|
||||||
/// <returns>This instance to permit chaining.</returns>
|
/// <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
|
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);
|
subquery(b, sub);
|
||||||
|
|
||||||
|
|||||||
@@ -122,6 +122,8 @@ namespace DynamORM.Mapper
|
|||||||
|
|
||||||
internal ParameterSpec UpdateCommandParameter { get; set; }
|
internal ParameterSpec UpdateCommandParameter { get; set; }
|
||||||
|
|
||||||
|
internal ParameterSpec DeleteCommandParameter { get; set; }
|
||||||
|
|
||||||
#endregion Type command cache
|
#endregion Type command cache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +142,8 @@ namespace DynamORM.Mapper
|
|||||||
|
|
||||||
internal string UpdateCommandText { get; set; }
|
internal string UpdateCommandText { get; set; }
|
||||||
|
|
||||||
|
internal string DeleteCommandText { get; set; }
|
||||||
|
|
||||||
#endregion Type command cache
|
#endregion Type command cache
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,3 +65,8 @@ using System.Runtime.InteropServices;
|
|||||||
[assembly: AssemblyVersion("1.1.0.1")]
|
[assembly: AssemblyVersion("1.1.0.1")]
|
||||||
[assembly: AssemblyFileVersion("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