use*_*388 4 vb.net asp.net-mvc entity-framework asp.net-mvc-3
在以下代码中,我试图获取当前登录用户的配置文件.
Dim userProfile = db1.UserProfiles.Where(Function(p) p.UserId = Membership.GetUser.ProviderUserKey).Single
Run Code Online (Sandbox Code Playgroud)
错误是"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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
编辑: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
Run Code Online (Sandbox Code Playgroud)
这应该更好,因为=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 Take和Where组件合并到一个SQL表达式中.您可以通过调用ToArray ToList或强制L2E命中服务器ToDictionary.该表达式可以通过将其更改为:
db1.UserProfiles.Skip(10).Take(30).ToArray().Where(Function(p) p.UserId = Membership.GetUser.ProviderUserKey)
该ToArray部队的SQL语句的执行,给你一个.NET数组,它不支持复杂lambas.