2012-02-09 9 views
0

従業員のリストを表示するページを作成しようとしています。複数のアイテムを返すLINQ式のメンバーシップデータを取得中にエラーが発生しました

すべての従業員認証データは、名前のような他のデータがEmployeesという名前の関連テーブルに格納された.NETメンバーシップテーブルに格納されます。ここで

は、従業員のリストを取得している私のコードです:

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 does not recognize the method 'System.Web.Security.MembershipUser GetUser(System.Object)' method, and this method cannot be translated into a store expression.

私はいくつかの研究をした、と私は外Membership.GetUser機能を引く必要があることがわかりましたのLINQ式の。これは、私が従業員を1人しか雇っていない場合にはうまくいくはずですが、リストを返すので、各繰り返しごとにユーザーが異なることになります。

これをどのように修正できますか?

答えて

2

あなたはSelect(..)ToArray()を挿入すると、「クライアント」側で、あなたの選択を評価することができます。この場合、EFで

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 
          }); 

Membership.GetUser方法を翻訳しようとしないでください。

EDIT: コメントで指摘されているように、この解決法は問題を解決しますが、別のものを導入します。N + 1はNが従業員の数であるところを選択します。

MemberShipテーブルをEFモデルにマップすることを避けるには、MemberShipテーブルとEmployeeテーブルの間にリレーションシップを作成することができます。次に、Membership.GetUser()を使用せずに、1つの選択ですべてのデータを取得できます。

+1

また、Employeesテーブルがaspnet_Membershipテーブルと同じデータベースにある場合は、それらの間にリンケージを作成して、e.Membership.Emailのようなものを使用できるようにする必要があります(あなたにはUserIDフィールドを作成する必要があります。 Employeeテーブルを作成し、適切なGUIDをロードしてから.edmxファイルにMembershipテーブルを追加してください) – Dave

+0

N人の従業員がいる場合、推奨されるLinqはN + 1データベースクエリを引き起こしますか?それは確かに大勢の従業員に拡大されませんか? @DaveがDB(したがってモデル)レベルでリンクを作成すると、単一のSQLクエリが可能になります。 –

+0

あなたの両方が正しいです。私は迅速な修正に焦点を当て、選択したN + 1を逃した。私は私の答えを更新しました。 – nemesv

関連する問題