2017-02-21 4 views
0

Ситуация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"); 
     } 
    } 
} 

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

Моя команда класса выглядит следующим образом:

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

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

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

Я выяснил несколько, возможные дубликаты на этот вопрос. Ближайший один такой:

Possible Duplicate 1

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

Вопросы

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

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

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

Благодаря @Evgeni для правых answer.Yes, вы можете объединить многую SQL-строку и просто отправить параметр в виде списка в одном раунде поездки , Замечательно.

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

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

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

Возможно, я напишу следующий вопрос. Черт.

ответ

2

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

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, он должен просто работать.

+1

Вы можете полностью заменить строки параметрами sql. Я обновлю код ... – Evgeni

+1

Aaaaahhh, ТЕПЕРЬ Я получаю, что вы пытались мне объяснить. Я буду оценивать это решение в конце недели, потому что у меня нет времени сегодня и завтра. Это выглядит очень многообещающе отсюда. Если он подходит, я буду отмечать ваш ответ как действительный и разместить свое решение в вопросе. Спасибо, Евгений! – Michael

+1

Это правильный ответ. Единственная проблема, с которой я столкнулся сейчас, заключается в том, что максимальное число параметров для SQL-Server составляет 2100 за команду. Поэтому, если у вас есть объект с 7 столбцами базы данных, вы можете отправить max 300 с помощью одной команды. Для 5000 вставок я остановил время 8 секунд, которое все еще замедляется, на мой взгляд. Я думаю, что нет никакого пути вокруг raw SQL. Я посмотрел в 3-х партийных библиотеках, которые могут обрабатывать массивные вставки для EF, и они также создают необработанный SQL. В любом случае - ваш ответ был абсолютно прав. Спасибо за вашу помощь! – Michael

Смежные вопросы