C# 过程指定的参数太多

C# 过程指定的参数太多,c#,asp.net,sql-server,C#,Asp.net,Sql Server,我在更新中遇到一些问题。我必须构建自定义的select,因此无法进行动态查询。我一直在尝试使用下面显示的代码更新我的数据库,但总是出现以下错误: 过程或函数UpdateUser指定的参数太多 我已经填写了所有的论点,没有更多,也没有更少。。。。怎么了 ASPX标记: <asp:SqlDataSource ID="AllUsers" runat="server" ConnectionString="<%$ ConnectionStrings:LocalSQL %>"

我在更新中遇到一些问题。我必须构建自定义的select,因此无法进行动态查询。我一直在尝试使用下面显示的代码更新我的数据库,但总是出现以下错误:

过程或函数UpdateUser指定的参数太多

我已经填写了所有的论点,没有更多,也没有更少。。。。怎么了

ASPX标记:

<asp:SqlDataSource ID="AllUsers" runat="server" 
    ConnectionString="<%$ ConnectionStrings:LocalSQL %>"
    SelectCommand="TodosOsUtilizadores" SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
存储过程:

CREATE PROCEDURE [dbo].UpdateUser
    @userid nvarchar(max),
    @username nvarchar(200),
    @email nvarchar(500),
    @isAnonimo bit, 
    @isLocked bit,
    @roleid nvarchar(max)
AS
    UPDATE Memberships 
    SET Email = @email, 
        IsLockedOut = @isLocked 
    WHERE 
        UserId = CAST(@userid as uniqueidentifier);

    UPDATE Users 
    SET UserName = @username, 
        IsAnonymous = @isAnonimo 
    WHERE 
        UserId = CAST(@userid AS uniqueidentifier);

    IF (@roleid IS NULL) 
    BEGIN
        UPDATE UsersInRoles 
        SET RoleId = CAST(roleid AS uniqueidentifier);
    END;
问题在于SqlDataSource如何工作,特别是冲突检测

作为:

ConflictDetection属性确定新旧值的参数是否应用于更新方法。例如,如果由SelectCommand属性指定的命令返回列名称和编号为的DataTable对象,并且ConflictDetection属性设置为OverwriteChanges值,则会为更新方法的名称和编号创建参数

因此,如果SelectCommand返回例如firstname,那么UpdateCommand中也有firstname参数,这就是导致错误的原因

不确定它是否有效,但一个简单的尝试是首先清除UpdateParameters集合:

using (SqlDataSource ds = AllUsers)
{
    Guid guid = new Guid();
    try
    {
        guid = Guid.Parse(Session["user_id"].ToString());
    }
    catch { guid = Guid.NewGuid(); }

    ds.UpdateCommand = "UpdateUser";
    ds.ConflictDetection = ConflictOptions.OverwriteChanges;
    ds.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;

    ds.UpdateParameters.Clear();

    ds.UpdateParameters.Add("userid", guid.ToString());
    ds.UpdateParameters.Add("username", "Diogo");
    ds.UpdateParameters.Add("email", "user_test@gmail.com");
    ds.UpdateParameters.Add("isAnonimo", "0");
    ds.UpdateParameters.Add("isLocked", "0");
    ds.UpdateParameters.Add("roleId", "");

    ds.Update();
    DetailsView1.DataBind();
}

请尝试指定参数,包括@?例如。Add@roleId, ;不要-Guid=Guid.Empty;查看如何使用Parameter.Add函数与Parameter.AddWithValue函数您还需要指定数据类型您使用它的方式我将更改Add to AddWithValue,这样数据库可以处理解析datatype@asawyer新Guid为您提供000-000…-还有很多给你!不是使用异常处理来设置GUID,而是考虑使用TyPARSE而只使用2行代码:GUID GUID;Guid.tryparSession[user\u id].ToString,out Guid;伦博里,我想你已经知道了。。我仍然认为,如果OP只是重构代码以使用SqlConnection&&SQLCommand对象,如果OP使用Command.Parameters.Add方法重载函数,那么这个问题就可以得到解决。如果OP使用Command.Parameters.Add方法重载函数,正确地执行了哪些操作,但不起作用。。你正在使一个简单的过程变得比它需要的更难我真的不知道你为什么要用这种方式来更新AllUsers当你需要做的只是从C代码调用一个普通的StoredProcedure然后使用SqlDataClient执行cmd.ExecuteOnQuery命令比在我的程序中旋转轮子要容易得多意见。UpdateParameters@userid=guid.ToString??好的,我试着把答案建立在原始问题的基础上——它在实际绑定场景中是有效的。由于您似乎忽略了SqlDataSource的数据绑定端,因此我也将使用标准的SqlConnection和SqlCommand
using (SqlDataSource ds = AllUsers)
{
    Guid guid = new Guid();
    try
    {
        guid = Guid.Parse(Session["user_id"].ToString());
    }
    catch { guid = Guid.NewGuid(); }

    ds.UpdateCommand = "UpdateUser";
    ds.ConflictDetection = ConflictOptions.OverwriteChanges;
    ds.UpdateCommandType = SqlDataSourceCommandType.StoredProcedure;

    ds.UpdateParameters.Clear();

    ds.UpdateParameters.Add("userid", guid.ToString());
    ds.UpdateParameters.Add("username", "Diogo");
    ds.UpdateParameters.Add("email", "user_test@gmail.com");
    ds.UpdateParameters.Add("isAnonimo", "0");
    ds.UpdateParameters.Add("isLocked", "0");
    ds.UpdateParameters.Add("roleId", "");

    ds.Update();
    DetailsView1.DataBind();
}