0

我们目前正在开发一个内部系统,使用存储库模式和实体框架 5 作为我们的 ORM。

我们在我们的数据库中有一堆我们调用的存储过程。其中一些过程具有相似的参数名称。因此,当我们调用执行存储过程时,如下所示:

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

生成的可枚举在第二次调用具有相似参数名称的另一个过程时失败,说:

用户代码未处理 ArgumentException:SqlParameter 已包含在另一个 SqlParameterCollection 中。

我们尝试将所有SqlParameters内容放入一个集合中,然后循环遍历该集合并将集合中的所有项目都归零,但这也失败了……非常好。

有没有办法在这个堆栈跟踪中访问和操作对象数组?

在 System.Data.SqlClient.SqlParameterCollection.Validate(Int32 index, Object value)
在 System.Data.SqlClient.SqlParameterCollection.AddRange(Array values)
在 System.Data.Objects.ObjectContext.CreateStoreCommand(String commandText, Object[] 参数)
在 System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, MergeOption mergeOption, Object[] 参数)
在 System.Data.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, Object[] 参数)
在 System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery[TElement](String sql,Object[] 参数
在 System.Data.Entity.Internal.InternalContext.ExecuteSqlQueryAsIEnumerable[TElement](String sql, Object[] 参数)
在 System.Data.Entity.Internal.InternalContext.ExecuteSqlQuery(Type elementType, String sql, Object[] 参数)
在 System .Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
在 System.Data.Entity.Internal.InternalSqlQuery 1 源) 1.GetEnumerator()
at System.Linq.Enumerable.First[TSource](IEnumerable

4

5 回答 5

2

你可以这样做:

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

它将绑定变量obj,之后你可以调用obj多少次你想要的sqlParameter没有问题。

于 2015-05-20T20:29:28.790 回答
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 ID=@Id 
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; }  
   }

在这里,我正在创建一个名为 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;

点击这里

于 2014-10-06T19:12:21.110 回答
0

我无法解决这个问题,内置 SqlQuery 方法中的命令对象似乎没有清除 sql 参数,但是我有一个解决方法。您可以根据当前连接创建自己的命令 - 但您将失去轻松映射返回类型的能力。

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();
}
于 2013-10-25T12:38:01.257 回答
0

您是否能够复制您的参数集合和其中的每个参数,而不是重复使用相同的参数实例?也许在某处有一个辅助方法可以自动为您复制它。

于 2013-10-31T14:07:52.527 回答
0

我找到了一个解决方案,可以解决这个问题。存储的 proc 调用用于实例化一个新的 DbContext,该 DbContext 将在执行后被释放,就像这样。

IEnumerable<ReturnType> Results = null;

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

自从采用这种方法以来,我没有遇到任何问题。

于 2013-11-14T21:56:31.947 回答