4

在下面的代码中,我试图获取当前登录用户的配置文件。

Dim userProfile = db1.UserProfiles.Where(Function(p) p.UserId = Membership.GetUser.ProviderUserKey).Single

错误是“LINQ to Entities 无法识别方法 'System.Object CompareObjectEqual(System.Object, System.Object, Boolean)' 方法,并且此方法无法转换为存储表达式。”

有谁知道这有什么问题,或者有更好的方法......而且,我怎样才能让它更安全;即如果没有找到记录,添加一个条件?

我正在使用 VB ASP.NET MVC 3。

谢谢你。

编辑:

这是我的新代码:

        Dim db1 As UserProfileDbContext = New UserProfileDbContext
        Dim user = Membership.GetUser()
        Dim key As Guid = user.ProviderUserKey
        Dim finalKey = key.ToString
        Dim userProfile = db1.UserProfiles.Where(Function(p) p.UserId = finalKey).Single
        Dim companyId = userProfile.CompanyId
4

1 回答 1

7

L2E 正在尝试将您的 Lamba 表达式呈现(p) p.UserId = Membership.GetUser.ProviderUserKey为可用于访问数据库的 SQL 表达式。

但是,Membership.GetUser()是一种 .NET 方法。L2E 抱怨它不知道如何将此方法呈现为 SQL 语法。

试试这个:

Dim user = Membership.GetUser()
Dim userProfile = db1.UserProfiles.Where(Function(p) p.UserId = user.ProviderUserKey).Single

编辑: MembershipUser.ProviderUserKey 是一个 CLR Object。SQL 无法比较两个对象,因此您需要在运行表达式之前对其进行强类型化。例如,如果您的用户密钥是String

Dim user = Membership.GetUser()
Dim key as String= user.ProviderUserKey
Dim userProfile = db1.UserProfiles.Where(Function(p) p.UserId = key).Single

这应该会更好,因为 L2E 可以理解简单的等式表达式=,并且可以将其呈现为等价的 SQL 表达式,例如:

SELECT * FROM Profiles WHERE UserId = @Argument,其中@Argument 由实体框架提供。

另外顺便说一句,L2E 将把链式调用分组到最后,所以表达式如下:

db1.UserProfiles.Skip(10).Take(30).Where(Function(p) p.UserId = Membership.GetUser.ProviderUserKey)

... 仍然会失败,因为 L2E 会将Skip TakeWhere组件组合成一个 SQL 表达式。ToArray ToList您可以通过调用或来强制 L2E 访问服务器ToDictionary。该表达式可以通过将其更改为:

db1.UserProfiles.Skip(10).Take(30).ToArray().Where(Function(p) p.UserId = Membership.GetUser.ProviderUserKey)

ToArray强制执行 SQL 语句,为您提供一个支持复杂 lambas.NET数组。

于 2012-08-01T19:48:43.110 回答