예제 #1
0
        internal static int SaveAll <T>(this IDbCommand dbCmd, IEnumerable <T> objs)
        {
            var saveRows = objs.ToList();

            var firstRow = saveRows.FirstOrDefault();

            if (Equals(firstRow, default(T)))
            {
                return(0);
            }

            var modelDef = typeof(T).GetModelDefinition();

            var firstRowId     = modelDef.GetPrimaryKey(firstRow);
            var defaultIdValue = firstRowId?.GetType().GetDefaultValue();

            var idMap = defaultIdValue != null
                ? saveRows.Where(x => !defaultIdValue.Equals(modelDef.GetPrimaryKey(x))).ToSafeDictionary(x => modelDef.GetPrimaryKey(x))
                : saveRows.Where(x => modelDef.GetPrimaryKey(x) != null).ToSafeDictionary(x => modelDef.GetPrimaryKey(x));

            var existingRowsMap = dbCmd.SelectByIds <T>(idMap.Keys).ToDictionary(x => modelDef.GetPrimaryKey(x));

            var rowsAdded = 0;

            IDbTransaction dbTrans = null;

            if (dbCmd.Transaction == null)
            {
                dbCmd.Transaction = dbTrans = dbCmd.Connection.BeginTransaction();
            }

            try
            {
                var dialect = dbCmd.Dialect();
                foreach (var row in saveRows)
                {
                    var id = modelDef.GetPrimaryKey(row);
                    if (id != defaultIdValue && existingRowsMap.ContainsKey(id))
                    {
                        dbCmd.Update(row);
                    }
                    else
                    {
                        if (modelDef.HasAutoIncrementId)
                        {
                            var newId  = dbCmd.Insert(row, commandFilter: null, selectIdentity: true);
                            var safeId = dialect.FromDbValue(newId, modelDef.PrimaryKey.FieldType);
                            modelDef.PrimaryKey.SetValue(row, safeId);
                            id = newId;
                        }
                        else
                        {
                            dbCmd.Insert(row, commandFilter: null);
                        }

                        rowsAdded++;
                    }

                    modelDef.RowVersion?.SetValue(row, dbCmd.GetRowVersion(modelDef, id));
                }

                dbTrans?.Commit();
            }
            finally
            {
                dbTrans?.Dispose();
                if (dbCmd.Transaction == dbTrans)
                {
                    dbCmd.Transaction = null;
                }
            }

            return(rowsAdded);
        }