我们目前正在开发一个内部系统,使用存储库模式和Entity Framework 5作为我们的ORM。
我们在数据库中有一堆存储过程,我们称之为。其中一些程序具有类似的参数名称。因此,当我们调用执行存储过程时,如下所示:
DbContext.Database.SqlQuery<ReturnType>(query, parameters)
在第二次调用具有类似参数名称的另一个过程时,生成的枚举失败,说:
用户代码未处理ArgumentException:SqlParameter已被另一个SqlParameterCollection包含。
我们已经尝试将所有SqlParameters
放入我们循环的集合中,并将集合中的所有项目归零,但这也失败了....光荣地。
有没有办法在此堆栈跟踪中访问和操作Object数组?
at System.Data.SqlClient.SqlParameterCollection.Validate(Int32 index,Object value)
在System.Data.SqlClient.SqlParameterCollection.AddRange(数组值)
在System.Data.Objects.ObjectContext.CreateStoreCommand(String commandText, Object []参数)
at System.Data.Objects.ObjectContext.ExecuteStoreQueryInternal [TElement](String commandText,String entitySetName,MergeOption mergeOption, Object [] parameters )
at System.Data.Objects.ObjectContext.ExecuteStoreQuery [TElement](String commandText, Object [] parameters )
在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(类型elementType,String sql,对象[]参数)
在System.Data.Entity.Internal.InternalSqlNonSetQuery.GetEnumerator()
在System.Data.Entity.Internal.InternalSqlQuery1.GetEnumerator()
1来源)
at System.Linq.Enumerable.First[TSource](IEnumerable
答案 0 :(得分:2)
你可以这样做:
List<ReturnType> obj = DbContext.Database.SqlQuery<ReturnType>(query, parameters).ToList();
它将绑定变量obj,之后你可以调用obj你想要多少次没有sqlParameter问题。
答案 1 :(得分: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();
}
答案 2 :(得分:0)
您是否能够复制参数集合和每个参数,而不是重复使用相同的参数实例?也许在某个地方有一个帮助器方法可以自动为你复制它。
答案 3 :(得分:0)
我找到了一个解决方案,解决了这个问题。存储的proc调用用于实例化将在执行后处理的新DbContext,如下所示。
IEnumerable<ReturnType> Results = null;
using (DbContext NewContext = new PrometheusEntities())
{
Results = NewContext.Database.SqlQuery<ReturnType>(query, parameters).ToList();
}
return Results;
自从采用这种方法以来,我没有遇到任何问题。
答案 4 :(得分: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;