C# 在返回多个项的LINQ表达式中获取成员资格数据时出错

C# 在返回多个项的LINQ表达式中获取成员资格数据时出错,c#,asp.net,linq,linq-to-entities,C#,Asp.net,Linq,Linq To Entities,我正在尝试创建一个显示员工列表的页面 所有员工身份验证数据都存储在.NET成员资格表中,其他数据(如名称)存储在名为Employees的相关表中 以下是我获取员工名单的代码: var viewModel = employees.OrderBy(e => e.Name). Select(e => new EmployeeViewModel {

我正在尝试创建一个显示员工列表的页面

所有员工身份验证数据都存储在.NET成员资格表中,其他数据(如名称)存储在名为Employees的相关表中

以下是我获取员工名单的代码:

var viewModel = employees.OrderBy(e => e.Name).
                            Select(e => new EmployeeViewModel
                            {
                                EmployeeId = e.EmployeeID,
                                Name = e.Name,
                                Email = Membership.GetUser(e.UserID).Email,
                                Active = e.Active
                            });
我得到这个错误:

LINQ to Entities无法识别方法“System.Web.Security.MembershipUser GetUser(System.Object)”方法,并且无法将此方法转换为存储表达式。

我做了一些研究,发现我需要将
Membership.GetUser
函数拉到LINQ表达式之外。如果我只得到一名员工,这将非常有效,但我会返回一个列表,因此用户在每次迭代中都会有所不同


有人知道我如何解决这个问题吗?

您可以在
选择(…)
之前插入
ToArray()
来评估“客户端”的选择:

在这种情况下,EF不要尝试转换
Membership.GetUser
方法

编辑: 正如评论中指出的,此解决方案虽然解决了您的问题,但引入了另一个问题:它将执行N+1选择,其中N是员工数


为了避免这种情况,您可以在EF模型中映射您的
成员资格
表,并且可以在
成员资格
和您的
员工
表之间创建关系。然后,您可以通过一次选择获取所有数据,而无需使用
Membership.GetUser()

,或者,如果Employees表与aspnet_Membership表位于同一数据库中,您可以在它们之间创建链接,允许您使用类似e.Membership.Email的内容(您必须在Employee表中创建一个UserID字段,并将适当的guid加载到其中,然后将成员资格表添加到.edmx文件中)如果有N名员工,建议的Linq将导致N+1个数据库查询,不是吗?当然,这不会扩展到大量员工。@Dave建议在数据库中创建链接(因此模型)级别将允许单个SQL查询。你们都是对的。我专注于快速修复,没有选择N+1。我已更新了我的答案。因为这是针对显示员工列表的网页,我怀疑在DB查询数量成为问题之前,您会开始分页列表。即使页面大小为10名员工,也会是10倍不过,你需要什么就有什么。
var viewModel = employees.OrderBy(e => e.Name)
                           .ToArray()
                           .Select(e => new EmployeeViewModel
                            {
                                EmployeeId = e.EmployeeID,
                                Name = e.Name,
                                Email = Membership.GetUser(e.UserID).Email,
                                Active = e.Active
                            });