【发布时间】:2015-11-18 03:52:41
【问题描述】:
我正在使用 Identity (2.2) 开发一个 ASP.NET 项目。我试图放在一起的一件事是数据网格,其中用户和角色将被加载到一个可以运行 CRUD 命令的数据网格上。存储选择语句没有问题:
CREATE PROCEDURE [dbo].SelectUsersRoles
AS
SET NOCOUNT ON;
SELECT
p.Id, p.Email, p.PhoneNumber, p.LockoutEnabled, p.UserName,
p.AspNetUserRole, AspNetRoles.Name
FROM
AspNetUsers AS p
INNER JOIN
AspNetUserRoles ON p.Id = AspNetUserRoles.UserId
INNER JOIN
AspNetRoles ON AspNetUserRoles.RoleId = AspNetRoles.Id
GO
这选择了数据,我可以很好地加载网格。在reviewing this question 和this one 之后,我的想法是正确的更新代码应该是:
[编辑,运行存储过程更新如下,同样的问题]
CREATE PROCEDURE [dbo].UpdateUserRoles
(
@Email nvarchar(256),
@UserName nvarchar(256),
@PhoneNumber nvarchar(MAX),
@LockoutEnabled bit,
@original_ID nvarchar(128)
)
AS
SET NOCOUNT ON;
UPDATE p
SET p.Email = @Email,
p.Username = @UserName,
p.PhoneNumber = @PhoneNumber,
p.LockoutEnabled = @LockoutEnabled
FROM [AspNetUsers] AS p
INNER JOIN [AspNetUserRoles] AS r ON p.ID = r.UserID
INNER JOIN [AspNetRoles] AS b ON r.RoleID = b.ID
WHERE p.ID = @original_ID
GO
如果我尝试使用查询生成器,我注意到 VS'13 会自动向其中添加 CROSS JOIN 语句:[并且通常会降低可读性]
UPDATE p
SET p.Email = @Email, p.UserName = @UserName,
p.PhoneNumber = @PhoneNumber, p.LockoutEnabled = @LockoutEnabled
FROM
AspNetUsers AS p
INNER JOIN
AspNetUserRoles AS r ON p.Id = r.UserId
INNER JOIN
AspNetRoles AS b ON r.RoleId = b.Id
CROSS JOIN
p
WHERE
(p.Id = @original_ID)
当我尝试运行查询时,这会不断抛出“p”是无效对象的错误。
我是否缺少一些简单的东西,或者将其拆分为连续的更新命令会更好?最终目标是更新用户信息(即电话号码)以及分配给用户的角色。
只是为了设置有问题的数据库,我认为您可以从 Visual Studio 启动任何新的 MVC/Web 表单模板,创建一些用户并设置一些角色。
【问题讨论】:
-
您可以使用存储过程而不是将代码保留在应用程序中吗?它提供了更好的分离来获取数据层中的数据和应用层之外的数据。它还可以轻松解决这类问题。
-
@SeanLange 据我所知,我正在尝试使用存储过程。我没有通过尝试将 UPDATE 采石场添加到存储的 SELECT 采石场(有效)。我想我可以将它作为第一个存储形式起草……但这不会改变实际的采石场部分吗?
-
那么第一个代码sn -p就是一个程序。第二个(更新语句)不是第一个过程的一部分,而且看起来根本不是一个过程。但如果没有上下文,就很难说。我非常怀疑工作室会在存储过程中为您的查询添加交叉连接。这似乎有点奇怪。
-
@SeanLange 一旦我粘贴代码,似乎采石场生成器正在执行此操作,然后单击“确定”或在执行中对其进行测试。如果我放弃该步骤并仅存储该过程,那么当我调用它时,我会得到相同的“p”是无效对象错误。我将尝试不重命名任何表,但我认为这是错误的?
-
不要使用查询生成器。这就是问题的开始。然后,您需要删除要更新的列列表中的别名。 (更新 p 设置 Email = @Email...)
标签: sql asp.net sql-server asp.net-mvc