0

我們正在開發一個內部系統,使用存儲庫模式和實體框架5作爲我們的ORM。使用實體框架執行存儲過程

我們在我們的數據庫中有一堆存儲過程,我們稱之爲。其中一些程序具有相似的參數名稱。因此,當我們撥打電話,以執行存儲過程,就像這樣:

DbContext.Database.SqlQuery<ReturnType>(query, parameters) 

產生的枚舉失敗,第二次調用同一個類似的參數名稱的另一個過程,他說:

ArgumentException的是未處理通過用戶代碼:SqlParameter已被另一個SqlParameterCollection包含。

我們試圖把所有SqlParameters到一個集合,我們遍歷和空出的集合中的所有項目,但這個失敗以及....光榮。

有沒有辦法在這個堆棧跟蹤中訪問和操作Object數組?

在System.Data.SqlClient.SqlParameterCollection.Validate(的Int32索引,對象的值)
在System.Data.SqlClient.SqlParameterCollection.AddRange(數組值)
在System.Data.Objects.ObjectContext。 CreateStoreCommand(字符串的CommandText,對象[]參數
在System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal [TElement](字符串的CommandText,字符串entitySetName,MergeOption mergeOption,對象[]參數
在System.Data .Objects.ObjectContext.Execu teStoreQuery [TElement](字符串的CommandText,對象[]參數
在System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery [TElement](字符串SQL,對象[]參數
在System.Data。 Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable [TElement](字符串SQL,對象[]參數
在System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(類型的ElementType,字符串SQL,對象[]參數
at System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
在System.Data.Entity.Internal.InternalSqlQuery 1.GetEnumerator()
at System.Linq.Enumerable.First[TSource](IEnumerable
1源)

+0

你可以顯示更多的代碼和錯誤發生在哪一行? – PilotBob

回答

0

我發現了一個解決方案,圍繞這個問題的工作。存儲的proc調用被用來實例化一個新的DbContext,它將在執行後被處理,像這樣。

IEnumerable<ReturnType> Results = null; 

using (DbContext NewContext = new PrometheusEntities()) 
{ 
    Results = NewContext.Database.SqlQuery<ReturnType>(query, parameters).ToList();  
}  
return Results; 

自從使用這種方法以來,我還沒有遇到任何問題。

0

我一直沒能解決的問題,內置的SqlQuery類方法似乎並沒有明確的SQL參數的Command對象,但是我有一個工作。 您可以根據當前連接創建自己的命令 - 但是您將失去輕鬆映射返回類型的能力。

public void CallStoredProc(string query, List<SqlParameter> parameters) 
{ 
    //this.Database.Connection (this = DBContext) 
    System.Data.Common.DbCommand cmd = this.Database.Connection.CreateCommand(); 
    cmd.CommandText = query; 

    // add params 
    foreach (var item in parameters) 
    { 
     cmd.Parameters.Add(item); 
    } 

    // execute query (not differed) 
    var reader = cmd.ExecuteReader(); 


    // attempt to read rows 
    if (reader.HasRows) 
    { 
     while (reader.Read()) 
     { 
      // row level data 
     } 
    } 

    // cleanup 
    cmd.Parameters.Clear(); 
    cmd.Dispose(); 
} 
0

您能夠使您的參數集合的副本,並在而不是再使用參數相同情況下的每個參數?也許有一個輔助方法可以自動爲你複製。

+0

應該在執行DbContext.Database.SqlQuery (query,parameters)之前立即執行此副本嗎? 另外我想問一下。假設結果傳遞給一個IEnumerable對象,其內容僅在IEnumerable迭代完成後纔會填充,那麼何時清除輔助方法生成的副本最適合? – Zjybra

+0

看看你是如何做到這一點可能很有用。你是否只是使用相同的SQLQuery或以上?也許在原始問題中添加一些更多的細節(代碼?)。 –

+0

這不一定是一遍又一遍地調用相同的查詢。 部分應用程序包含銷售團隊的儀表板,我們調用存儲過程來檢索與特定團隊關聯的活動,並且proc接受int> @TeamID類型的參數。 下一個被執行的proc也有一個> @TeamID參數,這就是錯誤得到提示的時候。 – Zjybra

0
Create Stored Procedure 
ALTER PROCEDURE [dbo].[sp_GelUserContactDetails] 
    ( 
    @Id INT=0, 
    @UserId int=0 
) 
AS 
    BEGIN 
SELECT M.Id AS UserID, M.FirstName as Name,M.Designation,M.CompanyName FROM dbo.Flo_MemberShip M 
WHERE [email protected] 
END 

//創建存儲過程,持有類MyContacts

public class MyContacts 
    { 
    public int UserID { get; set; } 
    public string Designation { get; set; } 
    public string Name { get; set; } 
    public string Organization { get; set; } 
    public string Image { get; set; } 
    public string RequestDate { get; set; } 
    public string IsContact { get; set; } 
    } 

這裏我創建一個實體that`s名字是MyContacts的結果。這裏MyContacts屬性名稱必須與存儲過程的select語句的返回列相同。

using (var context = new FLOEntities()) 
{ 
    string query = "sp_GelUserContactDetails @Id,@UserId"; 
    SqlParameter Id = new SqlParameter("@Id", selfId); 
    SqlParameter UserId = new SqlParameter("@UserId", userId); 
    obj = context.Database.SqlQuery<MyContacts>(query, Id, UserId).FirstOrDefault(); 
} 
return obj; 

click here

2

你可以做這樣的事情:

List<ReturnType> obj = DbContext.Database.SqlQuery<ReturnType>(query, parameters).ToList(); 

它將綁定變量OBJ,之後你可以調用obj的你要多少次沒有用的SqlParameter問題。