Entity Framework: выполнение нескольких команд в одном цикле

ситуация

У меня много параметризованных команд SQL. Я выполняю эти команды одну за другой в цикле и выглядит так:

public void SaveChanges()
{
    using (var ts = _Context.Database.BeginTransaction())
    {
        try
        {
            _Context.SaveChanges();

            foreach (var cmd in _Commands)
            {
                if (cmd.Parameter != null)
                {
                    _Context.Database.ExecuteSqlCommand(cmd.Sql, cmd.Parameter.ToArray()); 
                }
            }

            ts.Commit();
        }
        catch (Exception ex)
        {
            ts.Rollback();
            throw new Exception("SaveChanges");
        }
    }
}

Приведенный выше код работает, также откат транзакции работает, как ожидалось.

Мой командный класс выглядит так:

public class SqlBuilderCommand
{
    public string Sql { get; set; }

    public List<SqlParameter>  Parameter {get;set;}
}

Возможные дубликаты без конкретного решения

Я выяснил несколько возможных дубликатов этого вопроса. Наиболее близким является это:

Возможный дубликат 1

К сожалению, это не помогает мне с Entity Framework (или я просто не понимаю)

Вопросы

  1. Можно ли выполнить все команды в списке за один круг?

  2. Если нет, возможно ли это с ADO.NET?

РЕШЕНИЕ И НЕДОСТАТКИ / ОГРАНИЧЕНИЯ

Спасибо @Evgeni за правильный ответ. Да, вы можете объединить множество SQL-строк и просто отправить параметр в виде списка за один цикл. Замечательно.

Но есть ограничение с SQL-сервером. SQL-Server принимает максимум 2100 параметров с помощью одной команды. Поэтому, если у вас есть объект с 7 столбцами базы данных, максимальная массовая вставка составляет 300 объектов на команду. В противном случае вы получите исключение.

Если я сделаю это для 5000 объектов, это приведет к 17 объемным вставкам (5000/300). Я остановил время для 5000 объектов, и это все еще 8-9 секунд, что слишком медленно, потому что я знаю, что сырой SQL сделает это намного, намного быстрее.

На данный момент, я думаю, что нет никакого способа обойти необработанный SQL для меня, если кто-то не может сказать мне, что есть способ ускорить команды sql.

Возможно я напишу дополнительный вопрос к этому. Черт.

1 ответ

Решение

Технически вы можете выполнить несколько команд за один раз:

    var n1 = new SqlParameter("@name1", System.Data.SqlDbType.VarChar);
    n1.Value = "name 1 ";
    var u1 = new SqlParameter("@uid1", System.Data.SqlDbType.UniqueIdentifier);
    u1.Value = Guid.Parse("guid here");
    var n2 = new SqlParameter("@name2", System.Data.SqlDbType.VarChar);
    n2.Value = "name2";
    var u2 = new SqlParameter("@uid2", System.Data.SqlDbType.UniqueIdentifier);
    u2.Value = Guid.Parse("guid here");
    var sqlParams = new[]
    {
        n1, n2, u1, u2
    };

    using (var db = new DbContext("default"))
    {

        db.Database.ExecuteSqlCommand(@"
            Update property set name = @name1 where uid = @uid1; 
            Update property set name = @name2 where uid = @uid2;", sqlParams);
    }

Так что я думаю, если вы объедините свой sql, он должен просто работать.

Другие вопросы по тегам