Пример #1
0
        /// <summary>
        ///     An IQueryable&lt;T&gt; extension method that deletes all rows from the query without
        ///     retrieving entities.
        /// </summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="query">The query to delete rows from without retrieving entities.</param>
        /// <param name="batchDeleteBuilder">The batch builder action to change default configuration.</param>
        /// <returns>The number of rows affected.</returns>
        public static int Delete <T>(this IQueryable <T> query, Action <BatchDelete> batchDeleteBuilder) where T : class
        {
            var batchDelete = new BatchDelete();

            if (BatchDeleteManager.BatchDeleteBuilder != null)
            {
                BatchDeleteManager.BatchDeleteBuilder(batchDelete);
            }

            if (batchDeleteBuilder != null)
            {
                batchDeleteBuilder(batchDelete);
            }

            return(batchDelete.Execute(query));
        }
Пример #2
0
        /// <summary>Executes the batch delete operation.</summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="query">The query used to execute the batch operation.</param>
        /// <returns>The number of rows affected.</returns>
        public int Execute <T>(IQueryable <T> query) where T : class
        {
            // FIX query with visitor
            {
                var visitor = new BatchDeleteVisitor();
                visitor.Visit(query.Expression);

                if (visitor.HasOrderBy)
                {
                    query = query.Take(int.MaxValue);
                }

                if (visitor.HasTake || visitor.HasSkip)
                {
                    BatchSize = 0;
                }
            }

            string expression = query.Expression.ToString();

            if (Regex.IsMatch(expression, @"\.Where\(\w+ => False\)"))
            {
                return(0);
            }

            // GET model and info
#if EF5 || EF6
            var model  = query.GetDbContext().GetModel();
            var entity = model.Entity <T>();
            var keys   = entity.Info.Key.PropertyRefs;

            // SELECT keys names
            var queryKeys        = query.SelectByName(keys.Select(x => x.Name).ToList());
            var innerObjectQuery = queryKeys.GetObjectQuery();

            // CREATE command
            var command = CreateCommand(innerObjectQuery, entity);

            // EXECUTE
            var ownConnection = false;

            try
            {
                if (innerObjectQuery.Context.Connection.State != ConnectionState.Open)
                {
                    ownConnection = true;
                    innerObjectQuery.Context.Connection.Open();
                }

                if (command.GetType().Name == "NpgsqlCommand")
                {
                    command.CommandText = command.CommandText.Replace("[", "\"").Replace("]", "\"");
                    int totalRowAffecteds = command.ExecuteNonQuery();
                    return(totalRowAffecteds);
                }
                else if (command.Connection.GetType().Name.Contains("MySql"))
                {
                    int totalRowAffecteds = command.ExecuteNonQuery();
                    return(totalRowAffecteds);
                }
                else if (command.Connection.GetType().Name.Contains("Oracle"))
                {
                    int totalRowAffecteds = command.ExecuteNonQuery();
                    return(totalRowAffecteds);
                }
                else if (command.GetType().Name == "SqlCeCommand")
                {
                    int totalRowAffecteds = command.ExecuteNonQuery();
                    return(totalRowAffecteds);
                }
                else
                {
                    if (Executing != null)
                    {
                        Executing(command);
                    }

                    var rowAffecteds = (int)command.ExecuteScalar();
                    return(rowAffecteds);
                }
            }
            finally
            {
                if (ownConnection && innerObjectQuery.Context.Connection.State != ConnectionState.Closed)
                {
                    innerObjectQuery.Context.Connection.Close();
                }
            }
#elif EFCORE
            if (BatchDeleteManager.InMemoryDbContextFactory != null && query.IsInMemoryQueryContext())
            {
                var context = BatchDeleteManager.InMemoryDbContextFactory();

                var list = query.ToList();
                context.RemoveRange(list);
                context.SaveChanges();
                return(list.Count);
            }

            var dbContext = query.GetDbContext();
            var entity    = dbContext.Model.FindEntityType(typeof(T));
            var keys      = entity.GetKeys().ToList()[0].Properties;

            var queryKeys = query.SelectByName(keys.Select(x => x.Name).ToList());

            // CREATE command
            var command = CreateCommand(queryKeys, entity);

            // EXECUTE
            var ownConnection = false;

            try
            {
                if (dbContext.Database.GetDbConnection().State != ConnectionState.Open)
                {
                    ownConnection = true;
                    dbContext.Database.OpenConnection();
                }

                if (command.GetType().Name == "NpgsqlCommand")
                {
                    command.CommandText = command.CommandText.Replace("[", "\"").Replace("]", "\"");
                    int totalRowAffecteds = command.ExecuteNonQuery();
                    return(totalRowAffecteds);
                }
                else if (command.Connection.GetType().Name.Contains("MySql"))
                {
                    int totalRowAffecteds = command.ExecuteNonQuery();
                    return(totalRowAffecteds);
                }
                else
                {
                    if (Executing != null)
                    {
                        Executing(command);
                    }
                }

                var rowAffecteds = (int)command.ExecuteScalar();
                return(rowAffecteds);
            }
            finally
            {
                if (ownConnection && dbContext.Database.GetDbConnection().State != ConnectionState.Closed)
                {
                    dbContext.Database.CloseConnection();
                }
            }
#endif
        }
Пример #3
0
        /// <summary>Executes the batch delete operation.</summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="query">The query used to execute the batch operation.</param>
        /// <returns>The number of rows affected.</returns>
        public int Execute <T>(IQueryable <T> query) where T : class
        {
            // FIX query with visitor
            {
                var visitor = new BatchDeleteVisitor();
                visitor.Visit(query.Expression);

                if (visitor.HasOrderBy)
                {
                    query = query.Take(int.MaxValue);
                }

                if (visitor.HasTake || visitor.HasSkip)
                {
                    BatchSize = 0;
                }
            }

            string expression = query.Expression.ToString();

            if (Regex.IsMatch(expression, @"\.Where\(\w+ => False\)"))
            {
                return(0);
            }

            // GET model and info
#if EF5 || EF6
            var dbContext = query.GetDbContext();

#if EF6
            if (dbContext.IsInMemoryEffortQueryContext())
            {
                var context = query.GetDbContext();

                var list = query.ToList();
                context.Set <T>().RemoveRange(list);
                context.SaveChanges();
                return(list.Count);
            }
#endif

            var model = dbContext.GetModel();

            //get our table definitions for the requested type
            IEnumerable <TableDefinition> lsTableDefinitions = model.GetTableDefinitions <T>();

            //reverse the order so the most base table is the first
            TableDefinition tdBaseTableDefinition = lsTableDefinitions.OrderByDescending(i => i.Order).FirstOrDefault();

            //stop if there's nothing
            if (tdBaseTableDefinition == null)
            {
                throw new Exception("Could not find Entity meta data");
            }

            int rowsAffected = 0;

            // SELECT keys names
            var queryKeys        = query.SelectByName(tdBaseTableDefinition.Keys.Select(x => x.ColumnName).ToList());
            var innerObjectQuery = queryKeys.GetObjectQuery();

            // CREATE command
            var command = CreateCommand(innerObjectQuery, tdBaseTableDefinition);

            // WHERE 1 = 0
            if (command == null)
            {
                return(0);
            }

            // EXECUTE
            var ownConnection = false;

            try
            {
                if (innerObjectQuery.Context.Connection.State != ConnectionState.Open)
                {
                    ownConnection = true;
                    innerObjectQuery.Context.Connection.Open();
                }

                Executing?.Invoke(command);

#if EF5
                if (command.GetType().Name == "NpgsqlCommand")
                {
                    command.CommandText = command.CommandText.Replace("[", "\"").Replace("]", "\"");
                    rowsAffected       += command.ExecuteNonQuery();
                }
                else if (command.Connection.GetType().Name.Contains("MySql"))
                {
                    rowsAffected += command.ExecuteNonQuery();
                }
                else if (command.Connection.GetType().Name.Contains("Oracle"))
                {
                    rowsAffected += command.ExecuteNonQuery();
                }
                else if (command.GetType().Name == "SqlCeCommand")
                {
                    rowsAffected += command.ExecuteNonQuery();
                }
                else
                {
                    rowsAffected += (int)command.ExecuteScalar();
                }
#elif EF6
                var interceptionContext = new DbCommandInterceptionContext(dbContext.GetObjectContext().GetInterceptionContext());

                if (command.GetType().Name == "NpgsqlCommand")
                {
                    command.CommandText = command.CommandText.Replace("[", "\"").Replace("]", "\"");
                    rowsAffected       += DbInterception.Dispatch.Command.NonQuery(command, interceptionContext);
                }
                else if (command.Connection.GetType().Name.Contains("MySql"))
                {
                    rowsAffected += DbInterception.Dispatch.Command.NonQuery(command, interceptionContext);
                }
                else if (command.Connection.GetType().Name.Contains("Oracle") || command.Connection.GetType().Name.Contains("SQLite"))
                {
                    rowsAffected += DbInterception.Dispatch.Command.NonQuery(command, interceptionContext);
                }
                else if (command.GetType().Name == "SqlCeCommand")
                {
                    rowsAffected += DbInterception.Dispatch.Command.NonQuery(command, interceptionContext);
                }
                else
                {
                    rowsAffected += (int)DbInterception.Dispatch.Command.Scalar(command, interceptionContext);
                }
#endif
            }
            finally
            {
                if (ownConnection && innerObjectQuery.Context.Connection.State != ConnectionState.Closed)
                {
                    innerObjectQuery.Context.Connection.Close();
                }
            }

            return(rowsAffected);
#elif EFCORE
            if (BatchDeleteManager.InMemoryDbContextFactory != null && query.IsInMemoryQueryContext())
            {
                var context = BatchDeleteManager.InMemoryDbContextFactory();

                var list = query.ToList();
                context.RemoveRange(list);
                context.SaveChanges();
                return(list.Count);
            }

            var dbContext = query.GetDbContext();
            var entity    = dbContext.Model.FindEntityType(typeof(T));

            //go all the way to our base type
            while (entity.BaseType != null)
            {
                entity = entity.BaseType;
            }

            //get our keys
            var keys = entity.GetKeys().SelectMany(i => i.Properties);

            var queryKeys = query.SelectByName(keys.Select(x => x.Name).ToList());

            // CREATE command
            var command = CreateCommand(queryKeys, entity);

            // EXECUTE
            var ownConnection = false;

            int intRowsAffected = 0;

            try
            {
                if (dbContext.Database.GetDbConnection().State != ConnectionState.Open)
                {
                    ownConnection = true;
                    dbContext.Database.OpenConnection();
                }

                Executing?.Invoke(command);

                if (command.GetType().Name == "NpgsqlCommand")
                {
                    command.CommandText = command.CommandText.Replace("[", "\"").Replace("]", "\"");
                    intRowsAffected     = command.ExecuteNonQuery();
                }
                else if (command.Connection.GetType().Name.Contains("MySql"))
                {
                    intRowsAffected = command.ExecuteNonQuery();
                }
                else if (command.GetType().Name.Contains("Sqlite"))
                {
                    intRowsAffected = command.ExecuteNonQuery();
                }
                else
                {
                    intRowsAffected = (int)command.ExecuteScalar();
                }
            }
            finally
            {
                if (ownConnection && dbContext.Database.GetDbConnection().State != ConnectionState.Closed)
                {
                    dbContext.Database.CloseConnection();
                }
            }

            return(intRowsAffected);
#endif
        }
        /// <summary>Executes the batch delete operation.</summary>
        /// <typeparam name="T">The type of elements of the query.</typeparam>
        /// <param name="query">The query used to execute the batch operation.</param>
        /// <returns>The number of rows affected.</returns>
        public int Execute <T>(IQueryable <T> query) where T : class
        {
            if (query.Expression.ToString().Contains(".Where(x => False)"))
            {
                return(0);
            }

            // GET model and info
#if EF5 || EF6
            var model  = query.GetDbContext().GetModel();
            var entity = model.Entity <T>();
            var keys   = entity.Info.Key.PropertyRefs;

            // SELECT keys names
            var queryKeys        = query.SelectByName(keys.Select(x => x.Name).ToList());
            var innerObjectQuery = queryKeys.GetObjectQuery();

            // CREATE command
            var command = CreateCommand(innerObjectQuery, entity);

            // EXECUTE
            var ownConnection = false;

            try
            {
                if (innerObjectQuery.Context.Connection.State != ConnectionState.Open)
                {
                    ownConnection = true;
                    innerObjectQuery.Context.Connection.Open();
                }

                if (command.GetType().Name == "NpgsqlCommand")
                {
                    command.CommandText = command.CommandText.Replace("[", "\"").Replace("]", "\"");
                    int totalRowAffecteds = 0;
                    int rowAffecteds      = 0;
                    do
                    {
                        if (rowAffecteds > 0 && BatchDelayInterval != 0)
                        {
                            Thread.Sleep(BatchDelayInterval);
                        }
                        rowAffecteds       = (int)command.ExecuteNonQuery();
                        totalRowAffecteds += rowAffecteds;
                    } while (rowAffecteds > 0);

                    return(totalRowAffecteds);
                }
                else if (command.Connection.GetType().Name.Contains("MySql"))
                {
                    int totalRowAffecteds = 0;
                    int rowAffecteds      = 0;
                    do
                    {
                        if (rowAffecteds > 0 && BatchDelayInterval != 0)
                        {
                            Thread.Sleep(BatchDelayInterval);
                        }
                        rowAffecteds       = (int)command.ExecuteNonQuery();
                        totalRowAffecteds += rowAffecteds;
                    } while (rowAffecteds > 0);

                    return(totalRowAffecteds);
                }
                else
                {
                    if (Executing != null)
                    {
                        Executing(command);
                    }

                    var rowAffecteds = (int)command.ExecuteScalar();
                    return(rowAffecteds);
                }
            }
            finally
            {
                if (ownConnection && innerObjectQuery.Context.Connection.State != ConnectionState.Closed)
                {
                    innerObjectQuery.Context.Connection.Close();
                }
            }
#elif EFCORE
            if (BatchDeleteManager.InMemoryDbContextFactory != null && query.IsInMemoryQueryContext())
            {
                var context = BatchDeleteManager.InMemoryDbContextFactory();

                var list = query.ToList();
                context.RemoveRange(list);
                context.SaveChanges();
                return(list.Count);
            }

            var dbContext = query.GetDbContext();
            var entity    = dbContext.Model.FindEntityType(typeof(T));
            var keys      = entity.GetKeys().ToList()[0].Properties;

            var queryKeys = query.SelectByName(keys.Select(x => x.Name).ToList());

            // CREATE command
            var command = CreateCommand(queryKeys, entity);

            // EXECUTE
            var ownConnection = false;

            try
            {
                if (dbContext.Database.GetDbConnection().State != ConnectionState.Open)
                {
                    ownConnection = true;
                    dbContext.Database.OpenConnection();
                }

                if (Executing != null)
                {
                    Executing(command);
                }

                var rowAffecteds = (int)command.ExecuteScalar();
                return(rowAffecteds);
            }
            finally
            {
                if (ownConnection && dbContext.Database.GetDbConnection().State != ConnectionState.Closed)
                {
                    dbContext.Database.CloseConnection();
                }
            }
#endif
        }