예제 #1
0
        // gets the current RK values (including the modifications)
        internal object[] GetCurrentRKValues()
        {
            List <object> values        = new List <object>();
            var           currentValues = PropertyAccessor.GetValues(this);

            foreach (var column in NodeMap.SortedRKColumns)
            {
                var columnZ = column.ID.ColumnZ;
                values.Add(currentValues[columnZ - 1]);
            }

            return(values.ToArray());
        }
예제 #2
0
        internal static Result <T> InsertGo <T>(Assembly client, DbRow row, bool identityInsert, ConnectBy connectBy)
            where T : DbRow
        {
            var name = Text.NotAvailable;

            try
            {
                var connectable = GetInsertBody <T>(client, row, identityInsert, connectBy, Text.Method.InsertGo, ref name);
                var result      = connectable.Go <T>();
                if (result.RowCount > 0)
                {
                    PropertyAccessor.SetValues(row, PropertyAccessor.GetValues(result.First()));
                    row.SetStatus(DbRowStatus.Loaded);

                    // has rowversion & it is not RK
                    if (row.HasNonRKRowversion)
                    {
                        Crud.ReloadGo <T>(client, row, false, connectBy, true);
                    }
                    else
                    {
                        // rowversion column is null:
                        var map = DbMapping.TryGetNodeMap(row);
                        if (map.HasRowversion && row.GetRowversionValue() == null)
                        {
                            row.SetStatus(DbRowStatus.Faulted);
                        }
                        else
                        {
                            row.SetStatus(DbRowStatus.Loaded);
                        }
                    }
                }

                result.FinalizeCrud();
                return(result);
            }
            catch (QueryTalkException)
            {
                throw;
            }
            catch (System.Exception ex)
            {
                throw Crud.ClrException(ex, name, Text.Method.InsertGo);
            }
        }
예제 #3
0
        private static List <JsonProperty> ReflectClass(Type type)
        {
            QueryTalkException exception;
            Type clrType;
            bool cached = false;

            List <JsonProperty> jsonCacheValue;

            cached = Cache.JsonCache.TryGetValue(type, out jsonCacheValue);
            if (!cached)
            {
                jsonCacheValue = new List <JsonProperty>();
                var properties = type.GetReadableProperties();
                var ix         = 0;
                var valid      = false;
                foreach (var property in properties)
                {
                    var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception);
                    if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                    {
                        continue;
                    }

                    if (!cached)
                    {
                        jsonCacheValue.Add(new JsonProperty(property.Name, clrType, PropertyAccessor.Create(type, property)));
                    }

                    ++ix;
                    valid = true;
                }

                if (!valid)
                {
                    throw new QueryTalkException("JsonConverter.ToJson<T>", QueryTalkExceptionType.InvalidDataClass,
                                                 String.Format("type = {0}", type), Text.Method.ToJson);
                }

                Cache.JsonCache[type] = jsonCacheValue;
            }

            return(jsonCacheValue);
        }
예제 #4
0
        internal object GetOriginalRowversionValue()
        {
            if (NodeMap.RowversionColumn == null)
            {
                return(null);
            }

            object value;
            var    columnZ = NodeMap.RowversionColumn.ID.ColumnZ;

            if (_originalValues != null && _originalValues.TryGetValue(columnZ, out value))
            {
                return(value);
            }
            else
            {
                return(PropertyAccessor.GetValues(this)[columnZ - 1]);
            }
        }
예제 #5
0
        private static List <IPropertyAccessor> _GetDbRowsGetters(bool withRowID, Type type, PropertyInfo[] properties)
        {
            List <IPropertyAccessor> getters = new List <IPropertyAccessor>();

            foreach (var property in properties)
            {
                getters.Add(PropertyAccessor.Create(type, property));
            }

            if (withRowID)
            {
                Cache.IRowAccessors[type] = getters;
            }
            else
            {
                Cache.PropertyAccessors[type] = getters;
            }

            return(getters);
        }
예제 #6
0
        internal object[] GetOriginalRKValues()
        {
            List <object> values        = new List <object>();
            var           currentValues = PropertyAccessor.GetValues(this);

            foreach (var column in NodeMap.SortedRKColumns)
            {
                object value;
                var    columnZ = column.ID.ColumnZ;
                if (_originalValues != null && _originalValues.TryGetValue(columnZ, out value))
                {
                    values.Add(value);
                }
                else
                {
                    values.Add(currentValues[columnZ - 1]);
                }
            }

            return(values.ToArray());
        }
예제 #7
0
        // anticipated:
        //   Row has a rowversion column.
        internal object GetRowversionValue()
        {
            var columnZ = NodeMap.RowversionColumn.ID.ColumnZ;

            return(PropertyAccessor.GetValues(this)[columnZ - 1]);
        }
예제 #8
0
        // isSilent:
        //   if true, then this method is used by other CRUD method (.UpdateGo/.InsertGo) which requires special treatment.
        internal static Result <T> ReloadGo <T>(Assembly client, DbRow row, bool forceMirroring, ConnectBy connectBy,
                                                bool isSilent = false)
            where T : DbRow
        {
            var name = Text.NotAvailable;

            try
            {
                ColumnSelector selector = forceMirroring ? ColumnSelector.All : ColumnSelector.RK;
                if (isSilent)
                {
                    selector = ColumnSelector.RK;
                }

                if (row == null)
                {
                    throw new QueryTalkException("Crud.GoReload", QueryTalkExceptionType.ArgumentNull, "row = null", Text.Method.ReloadGo);
                }

                Crud.CheckTable(row, Text.Method.ReloadGo);

                List <ParameterArgument> args = new List <ParameterArgument>();

                var map = DbMapping.TryGetNodeMap(row);
                name = map.Name.Sql;

                if (forceMirroring)
                {
                    if (!row.GetStatus().IsUpdatable())
                    {
                        var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue());
                        throw new QueryTalkException("Crud.ReloadGo", QueryTalkExceptionType.InvalidMirroring,
                                                     arguments, Text.Method.ReloadGo).SetObjectName(map.Name.Sql);
                    }
                }

                object[] originalValues;

                if (selector == ColumnSelector.All)
                {
                    if (map.HasRowversion)
                    {
                        originalValues = new object[] { row.GetOriginalRowversionValue() };
                    }
                    else
                    {
                        originalValues = row.GetOriginalValues();
                    }
                }
                // RK selector
                else
                {
                    originalValues = row.GetOriginalRKValues();
                }

                for (int i = 0; i < originalValues.Length; ++i)
                {
                    args.Add(new ParameterArgument(new Value(originalValues[i])));
                }

                args.Add(map.Name);

                if (selector == ColumnSelector.All)
                {
                    args.Add(new ParameterArgument(map.BuildOptimisticPredicate(originalValues, 1)));
                }
                else
                {
                    args.Add(new ParameterArgument(map.BuildRKPredicate(originalValues, 1)));
                }

                var cpass = ReloadProc(row.NodeID, selector).Pass(args.ToArray());
                cpass.SetRootMap(row.NodeID);   // important!
                Connectable connectable = Reader.GetConnectable(client, row, cpass, connectBy);
                var         result      = connectable.Go <T>();

                // success
                if (result.RowCount > 0)
                {
                    PropertyAccessor.SetValues(row, result.First().GetOriginalValues());
                    row.SetStatus(DbRowStatus.Loaded);
                    return(new Result <T>(true, 0));
                }
                // not found
                else
                {
                    var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue());

                    if (!isSilent)
                    {
                        if (forceMirroring)
                        {
                            throw new QueryTalkException("Crud.ReloadGo", QueryTalkExceptionType.ConcurrencyViolation,
                                                         arguments, Text.Method.ReloadGo).SetObjectName(map.Name.Sql);
                        }
                        else
                        {
                            throw new QueryTalkException("Crud.ReloadGo", QueryTalkExceptionType.ReloadFailed,
                                                         arguments, Text.Method.ReloadGo).SetObjectName(map.Name.Sql);
                        }
                    }
                    else
                    {
                        row.SetStatus(DbRowStatus.Faulted);
                        return(new Result <T>(true, 0));
                    }
                }
            }
            catch (QueryTalkException ex)
            {
                Loader.TryThrowInvalidSqlOperationException(ex, name, Text.Method.ReloadGo);
                throw;
            }
            catch (System.Exception ex)
            {
                var ex2 = Crud.ClrException(ex, name, Text.Method.ReloadGo);
                Loader.TryThrowInvalidSqlOperationException(ex2, name);
                throw ex2;
            }
        }
예제 #9
0
        private static void _BuildClassOuterSelect(Type type, ref Type clrType, ref QueryTalkException exception, List <ViewColumnInfo> columns,
                                                   bool isEmpty, PropertyInfo[] properties, out List <IPropertyAccessor> getters, out int numberOfProperties,
                                                   StringBuilder sqlOuter, StringBuilder sqlEmpty)
        {
            numberOfProperties = properties.Length;
            if (numberOfProperties == 0)
            {
                throw new QueryTalkException("ViewConverter.ToView<T>", QueryTalkExceptionType.InvalidDataClass,
                                             String.Format("data class = {0}", type));
            }

            bool cached = Cache.PropertyAccessors.TryGetValue(type, out getters);

            if (!cached)
            {
                getters = new List <IPropertyAccessor>();
            }

            NodeMap rowMap  = null;
            bool    isDbRow = type.IsDbRow();

            if (isDbRow)
            {
                rowMap = DbMapping.GetNodeMap(type);
                if (rowMap.ID.Equals(DB3.Default))
                {
                    DbRow.ThrowInvalidDbRowException(type);
                }
            }

            // outer select:
            int i = 0;

            foreach (var property in properties)
            {
                string column;

                var clrTypeMatch = Mapping.CheckClrCompliance(property.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                ViewColumnInfo columnInfo;
                if (isDbRow)
                {
                    var rowColumn = rowMap.Columns.Where(a => a.ID.ColumnZ == i + 1).First();
                    column     = rowColumn.Name.Part1;
                    columnInfo = new ViewColumnInfo(column, rowColumn.DataType, rowColumn.IsNullable);
                    columns.Add(columnInfo);
                }
                else
                {
                    column     = property.Name;
                    columnInfo = new ViewColumnInfo(column, property.PropertyType, clrType);
                    columns.Add(columnInfo);
                }

                if (i != 0)
                {
                    sqlOuter.NewLineIndent(Text.Comma);
                    sqlEmpty.Append(Text.Comma);
                }

                var dataType = Mapping.ProvideDataType(columnInfo.DataType, clrType);
                AppendOuterColumn(sqlOuter, dataType, i + 1, column);

                if (isEmpty)
                {
                    AppendNullValueColumn(sqlEmpty, i + 1);
                }

                if (!cached)
                {
                    getters.Add(PropertyAccessor.Create(type, property));
                }

                ++i;
            }

            numberOfProperties = i;
            if (numberOfProperties == 0)
            {
                ThrowInvalidDataClassException(type);
            }

            if (!cached)
            {
                Cache.PropertyAccessors[type] = getters;
            }
        }
예제 #10
0
        private static Connectable GetUpdateBody <T>(Assembly client, DbRow row, bool forceMirroring, ConnectBy connectBy,
                                                     string method, ref string name, out NodeMap map)
            where T : DbRow
        {
            if (row == null)
            {
                throw new QueryTalkException("Crud", QueryTalkExceptionType.ArgumentNull, "row = null", method);
            }

            Crud.CheckTable(row, method);

            ColumnSelector selector = forceMirroring ? ColumnSelector.All : ColumnSelector.RK;

            List <ParameterArgument> args = new List <ParameterArgument>();

            map  = DbMapping.TryGetNodeMap(row);
            name = map.Name.Sql;

            if (forceMirroring)
            {
                if (!row.GetStatus().IsUpdatable())
                {
                    var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue());
                    throw new QueryTalkException("Crud.UpdateGo", QueryTalkExceptionType.InvalidMirroring,
                                                 arguments, Text.Method.UpdateGo).SetObjectName(map.Name.Sql);
                }
            }

            object[] originalValues;

            if (selector == ColumnSelector.All)
            {
                if (map.HasRowversion)
                {
                    originalValues = new object[] { row.GetOriginalRowversionValue() };
                }
                else
                {
                    originalValues = row.GetOriginalValues();
                }
            }
            // RK selector
            else
            {
                originalValues = row.GetOriginalRKValues();
            }

            for (int i = 0; i < originalValues.Length; ++i)
            {
                args.Add(new ParameterArgument(new Value(originalValues[i])));
            }

            var currentValues    = PropertyAccessor.GetValues(row);
            var updatableColumns = row.GetUpdatableColumns(forceMirroring);

            if (updatableColumns == null || updatableColumns.Length == 0)
            {
                return(null);
            }

            var valueParams = new Column[updatableColumns.Length];
            int j           = 0;

            foreach (var column in updatableColumns)
            {
                var value = new Value(currentValues[column.ID.ColumnZ - 1]);
                args.Add(new ParameterArgument(value));
                valueParams[j] = String.Format("@v{0}", j + 1);
                ++j;
            }

            args.Add(map.Name);
            if (selector == ColumnSelector.All)
            {
                args.Add(new ParameterArgument(map.BuildOptimisticPredicate(originalValues, 1)));
            }
            else
            {
                args.Add(new ParameterArgument(map.BuildRKPredicate(originalValues, 1)));
            }

            int[] modified = updatableColumns.Select(a => a.ID.ColumnZ).ToArray();

            args.Add(map.Columns
                     .Where(a => modified.Contains(a.ID.ColumnZ))
                     .OrderBy(a => a.ID.ColumnZ)
                     .Select(a => new Column(a.Name))
                     .ToArray());

            Column[] outputColumns;
            Column[] selectColumns;
            _getColumnsWithoutRowversion(map, out outputColumns, out selectColumns);

            var cpass = UpdateProc <T>(map, selector, valueParams, updatableColumns, outputColumns, selectColumns).Pass(args.ToArray());

            cpass.SetRootMap(row.NodeID);
            return(Reader.GetConnectable(client, row, cpass, connectBy));
        }
예제 #11
0
        internal static Async <Result <T> > UpdateGoAsync <T>(Assembly client, DbRow row, bool forceMirroring, ConnectBy connectBy,
                                                              Action <Result <T> > onCompleted)
            where T : DbRow
        {
            var     name = Text.NotAvailable;
            NodeMap map;

            Crud.CheckTable(row, Text.Method.UpdateGo);

            try
            {
                var connectable = GetUpdateBody <T>(client, row, forceMirroring, connectBy, Text.Method.UpdateGo, ref name, out map);

                // no columns to modify?
                if (connectable == null)
                {
                    return(Async <Result <T> > .CreateDefault <T>());
                }

                return(connectable.GoAsync <T>(result =>
                {
                    try
                    {
                        // success
                        if (result.ReturnValue == 1)
                        {
                            PropertyAccessor.SetValues(row, PropertyAccessor.GetValues(result.First()));
                            row.SetStatus(DbRowStatus.Loaded);
                        }
                        // concurrency violation
                        else
                        {
                            if (forceMirroring)
                            {
                                var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue());
                                throw new QueryTalkException("Crud.UpdateGoAsync", QueryTalkExceptionType.ConcurrencyViolation,
                                                             arguments, Text.Method.UpdateGoAsync).SetObjectName(map.Name.Sql);
                            }
                        }

                        result.FinalizeCrud();
                        onCompleted?.Invoke(result);
                    }
                    catch (QueryTalkException)
                    {
                        throw;
                    }
                    catch (System.Exception ex)
                    {
                        throw Crud.ClrException(ex, name, Text.Method.InsertGoAsync);
                    }
                }));
            }
            catch (QueryTalkException ex)
            {
                Loader.TryThrowInvalidSqlOperationException(ex, name, Text.Method.UpdateGo);
                throw;
            }
            catch (System.Exception ex)
            {
                var ex2 = Crud.ClrException(ex, name, Text.Method.UpdateGo);
                Loader.TryThrowInvalidSqlOperationException(ex2, name);
                throw ex2;
            }
        }
예제 #12
0
        internal static Result <T> UpdateGo <T>(Assembly client, DbRow row, bool forceMirroring, ConnectBy connectBy)
            where T : DbRow
        {
            var     name = Text.NotAvailable;
            NodeMap map;

            try
            {
                var connectable = GetUpdateBody <T>(client, row, forceMirroring, connectBy, Text.Method.UpdateGo, ref name, out map);

                // no columns to modify?
                if (connectable == null)
                {
                    return(new Result <T>(false, 0));
                }

                var result = connectable.Go <T>();

                // success
                if (result.ReturnValue == 1)
                {
                    PropertyAccessor.SetValues(row, PropertyAccessor.GetValues(result.First()));

                    // has rowversion & it is not RK
                    if (row.HasNonRKRowversion)
                    {
                        row.SetStatus(DbRowStatus.Loaded);
                        Crud.ReloadGo <T>(client, row, true, connectBy, true);
                    }
                    else
                    {
                        // rowversion column is null:
                        if (map.HasRowversion && row.GetRowversionValue() == null)
                        {
                            row.SetStatus(DbRowStatus.Faulted);
                        }
                        else
                        {
                            row.SetStatus(DbRowStatus.Loaded);
                        }
                    }

                    result.FinalizeCrud();
                    return(result);
                }
                // optimistic concurrency violation
                else
                {
                    if (forceMirroring)
                    {
                        var arguments = map.BuildExceptionReport(row.GetOriginalRKValues(), row.GetOriginalRowversionValue());
                        throw new QueryTalkException("Crud.UpdateGo", QueryTalkExceptionType.ConcurrencyViolation,
                                                     arguments, Text.Method.UpdateGo).SetObjectName(map.Name.Sql);
                    }
                    else
                    {
                        result.FinalizeCrud();
                        return(result);
                    }
                }
            }
            catch (QueryTalkException ex)
            {
                Loader.TryThrowInvalidSqlOperationException(ex, name, Text.Method.UpdateGo);
                throw;
            }
            catch (System.Exception ex)
            {
                var ex2 = Crud.ClrException(ex, name, Text.Method.UpdateGo);
                Loader.TryThrowInvalidSqlOperationException(ex2, name);
                throw ex2;
            }
        }
예제 #13
0
        internal static IEnumerable <T> PackRows <T>(IEnumerable source)
            where T : new()
        {
            if (source == null)
            {
                return(null);
            }

            Type targetType = typeof(T);
            Type sourceType = null;

            foreach (var row in source)
            {
                if (row == null)
                {
                    continue;
                }

                sourceType = row.GetType();
                break;
            }

            if (sourceType == null)
            {
                return(null);
            }

            TryCheckClassType(targetType);
            TryCheckClassType(sourceType);

            var sourceProperties = sourceType.GetReadableProperties();
            var targetProperties = targetType.GetWritableProperties();

            if (targetProperties.Length == 0)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("type = {0}", targetType), Text.Method.Pack);
            }
            if (sourceProperties.Length == 0)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("type = {0}", sourceType), Text.Method.Pack);
            }

            var sourceGetters = new List <IPropertyAccessor>();
            var targetGetters = new List <IPropertyAccessor>();

            bool match = false;
            Type clrType;
            QueryTalkException exception;
            var numberOfPropertiesUsed = 0;

            foreach (var targetProperty in targetProperties)
            {
                var clrTypeMatch = Mapping.CheckClrCompliance(targetProperty.PropertyType, out clrType, out exception);
                if (clrTypeMatch != Mapping.ClrTypeMatch.ClrMatch)
                {
                    continue;
                }

                var sourceProperty = sourceProperties.Where(p => p.Name == targetProperty.Name).FirstOrDefault();
                if (sourceProperty != null)
                {
                    if (Common.GetClrType(sourceProperty.PropertyType) != Common.GetClrType(targetProperty.PropertyType))
                    {
                        throw new QueryTalkException("ClassConverter.ToClass", QueryTalkExceptionType.PackPropertyMismatch,
                                                     String.Format("target property name = {0}{1}   target property type = {2}{1}   source property type = {3}",
                                                                   targetProperty.Name, Environment.NewLine, targetProperty.PropertyType, sourceProperty.PropertyType),
                                                     Text.Method.Pack);
                    }

                    match = true;

                    sourceGetters.Add(PropertyAccessor.Create(sourceType, sourceProperty));
                    targetGetters.Add(PropertyAccessor.Create(targetType, targetProperty));
                    ++numberOfPropertiesUsed;
                }
            }

            if (!match)
            {
                throw new QueryTalkException("ClassConverter.TryCheckClassType", QueryTalkExceptionType.InvalidPack,
                                             String.Format("target type = {0}{1}   source type = {2}",
                                                           targetType, Environment.NewLine, sourceType),
                                             Text.Method.Pack);
            }

            var rows = new HashSet <T>();

            foreach (var sourceRow in source)
            {
                if (sourceRow == null)
                {
                    continue;
                }

                var targetRow = new T();

                for (int i = 0; i < numberOfPropertiesUsed; i++)
                {
                    var value = sourceGetters[i].GetValue(sourceRow);
                    targetGetters[i].SetValue(targetRow, value);
                }

                rows.Add(targetRow);
            }

            return(rows);
        }
예제 #14
0
        private static Connectable GetInsertBody <T>(Assembly client, DbRow row, bool identityInsert, ConnectBy connectBy,
                                                     string method, ref string name)
            where T : DbRow
        {
            if (row == null)
            {
                throw new QueryTalkException("Crud", QueryTalkExceptionType.ArgumentNull, "row = null", method);
            }

            Crud.CheckTable(row, method);

            List <ParameterArgument> args = new List <ParameterArgument>();

            var map = DbMapping.TryGetNodeMap(row);

            name = map.Name.Sql;

            if (!map.HasIdentity)
            {
                identityInsert = false;
            }

            var insertableColumns = map.GetInsertableColumns(row, identityInsert);

            Column[] outputColumns;
            Column[] selectColumns;
            _getColumnsWithoutRowversion(map, out outputColumns, out selectColumns);

            PassChainer cpass;

            if (insertableColumns.Length > 0)
            {
                var currentValues = PropertyAccessor.GetValues(row);
                var valueParams   = new Column[insertableColumns.Length];
                int j             = 0;
                foreach (var column in insertableColumns)
                {
                    var value = new Value(currentValues[column.ID.ColumnZ - 1]);
                    value.Original = column.TryCorrectMinWeakDatetime(value.Original, row);
                    args.Add(new ParameterArgument(value));
                    valueParams[j] = String.Format("@v{0}", j + 1);
                    ++j;
                }

                args.Add(map.Name);
                args.Add(insertableColumns
                         .Select(a => new Column(a.Name))
                         .ToArray());

                cpass = InsertProc <T>(insertableColumns, valueParams, identityInsert, outputColumns, selectColumns)
                        .Pass(args.ToArray());
            }
            // default values:
            else
            {
                cpass = InsertProcDefaultValues <T>(outputColumns, selectColumns).Pass(map.Name);
            }

            cpass.SetRootMap(row.NodeID);
            return(Reader.GetConnectable(client, row, cpass, connectBy));
        }
예제 #15
0
        private static SubResult ProcessPackage_InsertRows <T>(Assembly client,
                                                               IEnumerable <T> package, NodeMap map, ConnectBy connectBy, Nullable <bool> identityInsert)
            where T : DbRow
        {
            if (package.Count() == 0)
            {
                return(new SubResult());
            }

            PassChainer cpass;
            List <ParameterArgument> args = new List <ParameterArgument>();
            var view    = ViewConverter.ConvertDbRowData(package, false, true);
            var columns = map.GetInsertableColumns(true).Select(a => new Column(a.Name)).ToArray();

            if (map.HasIdentity)
            {
                var identityPK = map.TryGetIdentityPK();
                if (identityInsert == false)
                {
                    var delta = ((IRow)package.First()).RowID;
                    args.Add(view);
                    args.Add(delta);                                                // @Delta
                    args.Add(identityPK.Name.Part1);                                // @Identity
                    args.Add(new Column(Designer.IsNull(                            // ISNULL(MAX(@Identity), 0)
                                            Designer.Max(Designer.Identifier("1", identityPK.Name.Part1)), 0)));
                    args.Add(new Column(String.Format("[1].[{0}] - @Delta + @LastID + 1", Text.Reserved.QtRowIDColumnName).E()));
                    args.Add(map.Name);                                             // @Table
                    args.Add(columns);                                              // @Columns
                    args.Add(map.GetColumns(1));                                    // @AllColumns
                    args.Add(map.BuildSelfRelation(1, 2).E());                      // @On
                    cpass = _insertRowsIntoIdentityProc.Pass(args.ToArray());
                }
                else
                {
                    args.Add(ViewConverter.ConvertDbRowData(package, false, true)); // #Rows
                    args.Add(map.Name);                                             // @Table
                    args.Add(columns);                                              // @Columns
                    args.Add(map.GetColumns(1));                                    // @AllColumns
                    args.Add(map.BuildSelfRelation(1, 2).E());                      // @On
                    cpass = _identityInsertRowsProc.Pass(args.ToArray());
                }
            }
            // non-identity table
            else
            {
                // pass arguments
                args.Add(ViewConverter.ConvertDbRowData(package, false, true));     // #Rows
                args.Add(map.Name);                                                 // @Table
                args.Add(columns);                                                  // @Columns
                args.Add(map.GetColumns(1));                                        // @AllColumns
                args.Add(map.BuildSelfRelation(1, 2).E());                          // @On
                cpass = _insertRowsProc.Pass(args.ToArray());
            }

            // execute
            cpass.SetRootMap(map.ID);
            var connectable = Reader.GetConnectable(client, cpass, connectBy);
            var result      = connectable.Go <T>();
            var data        = result.ToList();

            var computedIndexes = map.SortedComputedColumns.Select(a => a.ID.ColumnZ).ToArray();
            var j = 0;

            foreach (var row in package)
            {
                PropertyAccessor.SetValues(row, PropertyAccessor.GetValues(data[j++]), computedIndexes);
                row.SetStatus(DbRowStatus.Loaded);
            }

            // all rows inserted successfully or none
            return(new SubResult(true, result.RowCount));
        }