2017-02-21 98 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"); 
     } 
    } 
} 

上面的代碼工作,也transcaction回滾按預期工作。

我的命令類看起來是這樣的:

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

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

可能重複沒有具體的解決方案

我想通了一些,可能重複這一問題。最近的一個是這樣的:

Possible Duplicate 1

不幸的是,它並不能幫助我與實體框架(或者我只是不明白這一點)

問題

  1. 是否可以在一次往返中執行列表中的所有命令?

  2. 如果沒有,是否可以使用ADO.NET?

解決方案和缺點/限制

感謝@Evgeni爲右answer.Yes,您可以連接許多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,現在我明白了,你試圖向我解釋什麼。我將在本週末評估這個解決方案,因爲我今天和明天都沒有時間。從這裏看起來很有希望。如果適合,我會將您的答案標記爲有效,並在問題中發佈我的解決方案。謝謝Evgeni! – Michael

+1

這是正確的答案。我現在唯一的問題是,SQL-Server的最大參數數量是每個命令2100。所以如果你有一個包含7個數據庫列的對象,你可以用一個命令發送最多300個數據。對於5000個插頁,我停下了8秒鐘的時間,在我看來,這仍然很慢。我認爲沒有辦法繞過原始SQL。我看了第三方庫,它可以處理EF的批量插入,並且它們也生成原始SQL。無論如何 - 你的答案絕對正確。謝謝你的幫助! – Michael