我在 Visual Studio 2010 Beta 2(.NET framework 4.0 Beta 2)中使用 Entity Framework 。我从我的数据库创建了一个 Entity Framework .edmx 模型,并且我有一些多对多关系。
我的数据库架构的一个简单示例是
我现在正在编写自定义角色提供程序 (Inheriting System.Configuration.Provider.RoleProvider) 并开始编写 IsUserInRole(username, roleName) 的实现。
我编写的 LINQ-to-Entity 查询,在 SQL-Profiled 时,都生成了 CROSS JOIN 语句,而我想要的是它们到 INNER JOIN。
Dim query = From m In dc.Members
From r In dc.Roles
Where m.ID = 100 And r.Name = "Member"
Select m
我的问题几乎完全在这里描述:
Entity framework and many to many queries unusable?
我确信那里提供的解决方案效果很好,但是虽然我在 uni 学习了 Java 并且我基本上可以理解 C#,但我无法理解提供的这种 Lambda 语法,我需要在 VB 中获得一个类似的示例。我已经在网上浏览了半天的大部分时间,但我并没有接近我的答案。
所以请有人建议我如何在 VB 中构造一个 LINQ 语句,它可以在 SQL 中执行此等效操作:
SELECT rm.RoleID
FROM RoleMembership rm
INNER JOIN Roles r ON r.ID = rm.RoleID
INNER JOIN Members m ON m.ID = rm.MemberID
WHERE r.Name = 'Member' AND m.ID = 101
我将使用此查询来查看成员 101 是否在角色 3 中。
(我很感激我可能不需要在 SQL 中加入成员表,但我想在 LINQ 中我需要引入成员对象?)
更新:
我通过使用多种方法更接近:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim count As Integer
Using dc As New CBLModel.CBLEntities
Dim persons = dc.Members.Where(AddressOf myTest)
count = persons.Count
End Using
System.Diagnostics.Debugger.Break()
End Sub
Function myTest(ByVal m As Member) As Boolean
Return m.ID = "100" AndAlso m.Roles.Select(AddressOf myRoleTest).Count > 0
End Function
Function myRoleTest(ByVal r As Role) As Boolean
Return r.Name = "Member"
End Function
SQL Profiler 显示:
SQL:批量启动
SELECT
[Extent1].[ID] AS [ID],
... (all columns from Members snipped for brevity) ...
FROM [dbo].[Members] AS [Extent1]
RPC:已完成
exec sp_executesql N'SELECT
[Extent2].[ID] AS [ID],
[Extent2].[Name] AS [Name],
[Extent2].[Active] AS [Active]
FROM [dbo].[RoleMembership] AS [Extent1]
INNER JOIN [dbo].[Roles] AS [Extent2] ON [Extent1].[RoleID] = [Extent2].[ID]
WHERE [Extent1].[MemberID] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=100
SQL:批量完成
SELECT
[Extent1].[ID] AS [ID],
... (all columns from Members snipped for brevity) ...
FROM [dbo].[Members] AS [Extent1]
我不确定为什么它在内部连接语句中使用 sp_execsql 以及为什么它仍然运行选择来选择所有成员。
谢谢。
更新 2
我通过将上述“多种方法”转换为 lambda 表达式然后全部转换为一个查询来编写它,如下所示:
Dim allIDs As String = String.Empty
Using dc As New CBLModel.CBLEntities
For Each retM In dc.Members.Where(Function(m As Member) m.ID = 100 AndAlso m.Roles.Select(Function(r As Role) r.Name = "Doctor").Count > 0)
allIDs &= retM.ID.ToString & ";"
Next
End Using
但它似乎不起作用:“医生”不是一个存在的角色,我只是将它放在那里进行测试,但“allIDs”仍然设置为“100;”
这次 SQL Profiler 中的 SQL 是这样的:
SELECT
[Project1].*
FROM ( SELECT
[Extent1].*,
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[RoleMembership] AS [Extent2]
WHERE [Extent1].[ID] = [Extent2].[MemberID]) AS [C1]
FROM [dbo].[Members] AS [Extent1]
) AS [Project1]
WHERE (100 = [Project1].[ID]) AND ([Project1].[C1] > 0)
为简洁起见,我将成员表中所有列的列表变成了 *
如您所见,它只是忽略了“角色”查询。
最佳答案
这就是我使用 Lambda 表达式解决它的方法:
Public Overrides Function IsUserInRole(ByVal username As String, ByVal roleName As String) As Boolean
Dim retVal As Boolean
Using db As New CBLEntities
Dim theRole = db.Roles.Where(Function(x) x.Name = roleName)
retVal = theRole.Any(Function(r As Role) r.Members.Where(Function(m As Member) m.ID = username).Any())
End Using
Return retVal
End Function
关于vb.net - Entity Framework 多对多使用 VB.Net Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2243462/