2017-02-21 4 views
0

상황엔티티 프레임 워크 : 나는 많은 매개 변수가있는 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;} 
} 

가능한 중복 구체적인 해결책없이

나는이 질문에 대한 몇 가지 가능한 중복을 낸 것. 가장 가까운 사람은 이것이다 :

Possible Duplicate 1

불행하게도, 그것은 엔티티 프레임 워크 나에게 도움이되지 않습니다 (또는 난 그냥 그것을 얻을하지 않습니다)

질문

  1. 목록에서 모든 명령을 한 왕복으로 실행할 수 있습니까?

  2. 그렇지 않으면 ADO.NET에서 가능합니까?

솔루션과 단점/제한

덕분에 오른쪽 answer.Yes에 대한 @Evgeni하는 당신은 많은 SQL-문자열 연결하여 단 하나의 왕복 목록으로 매개 변수를 보낼 수 있습니다 . 훌륭합니다.

그러나 SQL Server에는 제한 사항이 있습니다. 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, 지금 당장 나에게 설명하려고했던 것. 나는 오늘과 내일은 시간이 없기 때문에 이번 주말에이 해결책을 평가할 것입니다. 여기에서 매우 유망 해 보입니다. 맞는다면, 나는 당신의 답변을 유효한 것으로 표시하고 나의 해결책을 질문에 게시 할 것입니다. Evgeni 감사합니다! – Michael

+1

이것은 올바른 대답입니다. SQL Server의 최대 매개 변수 수는 명령 당 2100입니다. 따라서 데이터베이스 열 7 개가있는 객체가있는 경우 한 명령으로 최대 300 개를 보낼 수 있습니다. 5000 개의 인서트에 대해서, 나는 8 초의 시간을 멈추었는데, 그것은 여전히 ​​내 의견으로는 느려진다. 원시 SQL과 관련된 방법은 없다고 생각합니다. 나는 in3rd 파티 라이브러리를 보았는데 EF에 대한 대량 삽입을 처리 할 수 ​​있으며 원시 SQL도 생성됩니다. 어쨌든 - 당신의 대답은 정확했습니다. 당신의 도움을 주셔서 감사합니다! – Michael