如何在我的应用程序中使用SELECT语句,该语句必须返回多个记录以显示某个字段的多个值(m:m关系)
我不知道你是否理解我的意思,但我会尝试用一个例子来解释它。
用户表
UsedId UserName -------- ---------- 1 Mike 2 Raul
HasPrivileges表
UsedId PrivilegeId -------- -------------- 1 1 1 2 1 3 2 2 2 3
特权表
PrivilegeId Privilege ------------- ------------ 1 Create 2 Edit 3 Delete
现在这是两个表用户和权限,它们之间具有多对多的关系,所以当我选择与他们拥有的权限相关联的所有用户时,我在这个示例中得到3个记录或行中的每个人Mike包含他拥有的特权。
现在我需要在我的应用程序中显示所有具有权限的用户的列表但是我不希望我的用户三次看到用户显示他的所有权限或其他任何其他我希望它显示
User Id : 1 Name : Mike Privileges : Create, Edit, Delete
或者接近这个的东西! 任何想法的人!??
您的标记中包含ASP.NET和C#。 考虑到您打算做的是一个表达问题,在表示层(即使用C#)而不是在数据层(即使用SQL)中进行。 这也更容易。
例如,如下所示: 使用LINQ将多行连接成单行(CSV属性)
Ikashef,正如Tomalak所说,抑制每个名称/权限行的重复名称是一个“表示层”问题,即如何向用户显示数据。
您要做的是查看ADO.NET DataTable以获取这些行:
Joe 1 Joe 7 Joe 8 Tom 3 Tom 7 Tom 8
DataTable有一个Rows属性,它包含一组行。 您可以迭代(即依次访问)Rows集合中的每个DataRow。 因此,请阅读ADO.NET DataTable对象和集合类以及“for each”语法。
好的,我可以通过当前问题确定3点(我在自己的项目中有类似的事情)。
按位
通过使用位域而不是连接表,您几乎可以消除其中一个表。 例如,不是将HasPrivilages与权限表一起存储….您可以这样做:
UsedId PrivilegeId -------- -------------- 1 1 1 2 1 3 2 2 2 3
可以等同于:
UsedId PrivilegeId -------- -------------- 1 7 (equivalent of Create, Edit and Delete) 2 6 (equivalent of Create and Delete)
这是因为Create = 1,Edit = 2和Delete = 4.组合,它们形成一个整数。 这可以使用按位运算来区分,例如&和| 生成权限组合。
您可以使用Flags
属性声明您的权限集
[Flags()] public enum Permissions { Create = 1, Edit = 2, Delete = 4 }
当您读回值时,枚举将为您计算实际权限,您可以通过执行以下操作在您的应用程序中进行操作:
bool canEdit = ((myUser.Permissions & Permissions.Edit) == Permissions.Edit);
如果您具有相应的权限枚举,则对该给定实例执行.ToString()
实际上将为您提供所需的权限数据。 但是,最好给枚举一个自定义属性,这样你就可以给每个值一个更好的名字,甚至使它与资源无关。
格式化演示文稿
你当然可以坚持你所拥有的,并使用Tim给出的例子。 迭代行并基本上预先计算文本。
在SQL中执行
有时,让SQL更容易完成工作。 我做了很多。 如果您只是获取DataTables而不是手动或使用LINQ读取它们,这是一个快速解决方案。 如果您使用的是SQL Server 2005或更高版本,则可以使用类似于以下内容的代码:
SELECT u.UserId, u.UserName AS [Name], ( SELECT DISTINCT Privilege + ', ' FROM Privileges p2 INNER JOIN HasPrivileges j ON j.PrivilegeId = p2.PrivilegeId WHERE j.UserId = u.UserId FOR XML PATH ('') ) AS [Privileges] FROM Users u INNER JOIN HasPrivileges h ON h.UserId = u.UserId GROUP BY u.UserId, UserName
这输出:
UserId Name Privileges ------- ----- ----------- 1 Mike Create, Delete, Edit, 2 Paul Delete, Edit,
这仍然不完美。 您必须将其加载到临时表中,并在每个Privileges列的末尾删除最后的“,”char,或者在C#代码中执行此操作。
无论如何只是想我会提供一些替代品,汤姆。