1

存储过程有效并删除了我想要的内容,但删除后仍然出现此错误:

数据读取器与指定的“AMSIdentity.Models.RemoveRoleFromUserViewModel”不兼容。类型的成员“RoleId”在数据读取器中没有同名的对应列。

我需要在上面运行没有此错误的代码

此代码使用 ASP.NET MVC 5 和 EF6 代码优先方法;我尝试使用此代码,但删除后总是抛出此错误。

这是我使用的操作方法

public ActionResult RemoveRoleFromUserConfirmed(string UserName, string RoleId)
{
        if (UserName == null && RoleId == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        SqlParameter param1 = new SqlParameter("@RoleId", RoleId);
        SqlParameter param2= new SqlParameter("@UserName", UserName);

        var remove = Identitydb.Database.SqlQuery<RemoveRoleFromUserViewModel>("admin.sp_RemoveUserFromRole @RoleId, @UserName",
            ((ICloneable)param1).Clone(),
            ((ICloneable)param2).Clone()).ToArray().ToList().FirstOrDefault();

        if (remove == null)
        {
            return HttpNotFound();
        }

        return RedirectToAction("Roles");
}

这是我使用的视图模型:

public class RemoveRoleFromUserViewModel
{
    [Key]
    [DisplayName("Role Id")]
    public string RoleId { get; set; }

    [DisplayName("Username")]
    public string UserName { get; set; }
}

这是存储过程代码:

ALTER PROCEDURE [Admin].[sp_RemoveUserFromRole] 
    @RoleId NVARCHAR(50), 
    @UserName NVARCHAR(50)
AS
BEGIN
    DELETE FROM AspNetUserRoles 
    WHERE UserId = (SELECT Id 
                    FROM AspNetUsers 
                    WHERE UserName = @UserName) 
      AND RoleId = @RoleId 
END

我希望这段代码会删除特定用户的角色。

4

2 回答 2

0

大家好,

我从@Jeroen Mostert 那里得到了答案,解决方案是使用(ExecuteSqlCommand)而不是(SqlQuery),因为我永远不会返回数据,我只执行带有两个参数的存储过程。

  • 这是答案
SqlParameter param1 = new SqlParameter("@RoleId", RoleId);
SqlParameter param2= new SqlParameter("@UserName", UserName);

//I change this line from SqlQuery to ExecuteSqlCommand
var remove = Identitydb.Database.ExecuteSqlCommand("admin.sp_RemoveUserFromRole @RoleId, @UserName", param1, param2);

非常感谢@Jeroen Mostert。
问候,
Ali Mosaad
软件开发人员

于 2019-05-21T05:46:45.227 回答
0

当您在存储过程中执行 DELETE 时,您需要“审核”被删除的内容。然后在该审计表上执行 SELECT。

您正在利用 sql server 的 OUTPUT 功能。

看:

https://docs.microsoft.com/en-us/sql/t-sql/statements/delete-transact-sql?view=sql-server-2017

和/或

https://www.sqlservercentral.com/articles/the-output-clause-for-insert-and-delete-statements

下面是您需要的 TSQL 的通用示例。

DROP  TABLE [dbo].[Patient]
GO

CREATE TABLE [dbo].[Patient]
(
    [PatientKey]                            BIGINT          NOT NULL IDENTITY(1, 1),
    [PatientUniqueIdentifier]               VARCHAR(256)    NOT NULL,
    [CreateDate]                            DATETIMEOFFSET NOT NULL,
    CONSTRAINT [UC_Patient_PatientUniqueIdentifier] UNIQUE (PatientUniqueIdentifier)
)

/* now insert 3 sets of rows, with different create-dates */
INSERT INTO dbo.Patient (PatientUniqueIdentifier, [CreateDate]) SELECT TOP 10 NEWID() , '01/01/2001' from sys.objects
INSERT INTO dbo.Patient (PatientUniqueIdentifier, [CreateDate]) SELECT TOP 10 NEWID() , '02/02/2002' from sys.objects
INSERT INTO dbo.Patient (PatientUniqueIdentifier, [CreateDate]) SELECT TOP 10 NEWID() , '03/03/2003' from sys.objects

SELECT * FROM dbo.Patient

/* everything above is just setting up the example */
/* below would be the "guts"/implementation of your stored procedure */


DECLARE @PatientAffectedRowsCount BIGINT

    DECLARE @PatientCrudActivityAuditTable TABLE ( [PatientUniqueIdentifier] VARCHAR(256), DatabaseKey BIGINT , MyCrudLabelForKicks VARCHAR(16));


        /* now delete a subset of all the patient rows , your delete will be whatever logic you implement */
        DELETE FROM [dbo].[Patient]
        OUTPUT  deleted.PatientUniqueIdentifier , deleted.PatientKey , 'mydeletelabel'
        INTO    @PatientCrudActivityAuditTable  ([PatientUniqueIdentifier] ,DatabaseKey , MyCrudLabelForKicks )
        WHERE
            CreateDate = '02/02/2002'

        /*you don't need this update statement, but i'm showing the audit table can be used with delete and update and insert (update here) */
        /*
        UPDATE [dbo].[Patient]
        SET     CreateDate = '03/03/2003'
        OUTPUT  inserted.PatientUniqueIdentifier , inserted.PatientKey, 'myupdatelabel'
        INTO    @PatientCrudActivityAuditTable  ([PatientUniqueIdentifier] ,DatabaseKey , MyCrudLabelForKicks)
        FROM    [dbo].[Patient] realTable
        WHERE CreateDate != '03/03/2003'
        */

        /* optionally, capture how many rows were deleted */
        SELECT @PatientAffectedRowsCount = @@ROWCOUNT


SELECT 'Rows that I Deleted' as MyLabel_YouCanRemoveThisColumn, DatabaseKey , PatientUniqueIdentifier FROM @PatientCrudActivityAuditTable

在我的示例中,您将针对从@PatientSurrogateKeyAudit 表返回的 PatientKey 和 PatientUniqueIdentifier 列编写 dotNet 序列化代码...(无论您使用什么风格、原始 IDataReader、ORM 工具等等)。

于 2019-05-20T13:34:26.667 回答