/// <summary> /// Insert the specified object /// </summary> public TModel Insert <TModel>(TModel value) { #if DEBUG var sw = new Stopwatch(); sw.Start(); try { #endif // First we want to map object to columns var tableMap = TableMapping.Get(typeof(TModel)); SqlStatement columnNames = this.CreateSqlStatement(), values = this.CreateSqlStatement(); foreach (var col in tableMap.Columns) { var val = col.SourceProperty.GetValue(value); if (val == null || !col.IsNonNull && ( val.Equals(default(Guid)) || val.Equals(default(DateTime)) || val.Equals(default(DateTimeOffset)) || val.Equals(default(Decimal)))) { val = null; } if (col.IsAutoGenerated && val == null) { continue; } columnNames.Append($"{col.Name}"); // Append value values.Append("?", val); values.Append(","); columnNames.Append(","); } values.RemoveLast(); columnNames.RemoveLast(); var returnKeys = tableMap.Columns.Where(o => o.IsAutoGenerated); // Return arrays var stmt = this.m_provider.Returning( this.CreateSqlStatement($"INSERT INTO {tableMap.TableName} (").Append(columnNames).Append(") VALUES (").Append(values).Append(")"), returnKeys.ToArray() ); // Execute lock (this.m_lockObject) { var dbc = this.m_provider.CreateCommand(this, stmt); try { if (returnKeys.Count() > 0 && this.m_provider.Features.HasFlag(SqlEngineFeatures.ReturnedInserts)) { using (var rdr = dbc.ExecuteReader()) if (rdr.Read()) { foreach (var itm in returnKeys) { object ov = null; if (MapUtil.TryConvert(rdr[itm.Name], itm.SourceProperty.PropertyType, out ov)) { itm.SourceProperty.SetValue(value, ov); } } } } else { dbc.ExecuteNonQuery(); } } finally { if (!this.IsPreparedCommand(dbc)) { dbc.Dispose(); } } } if (value is IAdoLoadedData) { (value as IAdoLoadedData).Context = this; } return(value); #if DEBUG } finally { sw.Stop(); this.m_tracer.TraceVerbose("INSERT executed in {0} ms", sw.ElapsedMilliseconds); } #endif }
/// <summary> /// Updates the specified object /// </summary> public TModel Update <TModel>(TModel value) { #if DEBUG var sw = new Stopwatch(); sw.Start(); try { #endif // Build the command var tableMap = TableMapping.Get(typeof(TModel)); SqlStatement <TModel> query = this.CreateSqlStatement <TModel>().UpdateSet(); SqlStatement whereClause = this.CreateSqlStatement(); foreach (var itm in tableMap.Columns) { var itmValue = itm.SourceProperty.GetValue(value); if (itmValue == null || itmValue.Equals(default(Guid)) || itmValue.Equals(default(DateTime)) || itmValue.Equals(default(DateTimeOffset)) || itmValue.Equals(default(Decimal))) { itmValue = null; } query.Append($"{itm.Name} = ? ", itmValue); query.Append(","); if (itm.IsPrimaryKey) { whereClause.And($"{itm.Name} = ?", itmValue); } } query.RemoveLast(); query.Where(whereClause); // Now update lock (this.m_lockObject) { var dbc = this.m_provider.CreateCommand(this, query); try { dbc.ExecuteNonQuery(); } finally { if (!this.IsPreparedCommand(dbc)) { dbc.Dispose(); } } } if (value is IAdoLoadedData) { (value as IAdoLoadedData).Context = this; } return(value); #if DEBUG } finally { sw.Stop(); this.m_tracer.TraceVerbose("UPDATE executed in {0} ms", sw.ElapsedMilliseconds); } #endif }