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は(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はCLRObjectです。SQLは2つのオブジェクトを比較できないため、式を実行する前に強く入力する必要があります。たとえば、ユーザーキーが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はとコンポーネントを1つのSQL式に結合するため、それでも失敗しSkip TakeますWhereToArray ToListまたはを呼び出すことにより、L2Eをサーバーに強制的にヒットさせることができますToDictionary。その式は、次のように変更することで有効にできます。

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

SQLステートメントのToArray実行を強制し、複雑なランバをサポートする.NET配列を提供します。

于 2012-08-01T19:48:43.110 に答える