2016-03-28 2 views
3

LINQPadでこのLINQクエリを処理しています。私は次のようなことをしています:LINQサブクエリを拡張メソッドに移動すると実行時にエラーが発生する

var perms = (from x in db.TableName // etc 
      select new ProfilePermission 
      { // etc 
      }); 

perms = perms.Concat(from x in db.TableName // etc 
      select new ProfilePermission 
      { // etc 
      }); 

var results = (from pi in db.AnotherTable 
       where pi.IsActive 
       select new MyViewModel 
       { 
        KeyId = pi.Id, 
        Permissions = (from pm in perms 
            where pi.ChildId == pm.ChildId 
            select pm) 
       } 

このサブクエリを使用すると動作します。だから、私は考えました、それを拡張メソッドに移してみましょう。私はこれをやってみました:

public static IQueryable<ProfilePermission> GetProfilePermissions 
    (
    this IMkpContext db 
    ) 
{ 
    var perms = (from x in db.TableName // etc 
      select new ProfilePermission 
      { // etc 
      }); 

    perms = perms.Concat(from x in db.TableName // etc 
      select new ProfilePermission 
      { // etc 
      }); 


    return perms; 
} 

var results = (from pi in db.AnotherTable 
       where pi.IsActive 
       select new MyViewModel 
       { 
        KeyId = pi.Id, 
        Permissions = (from pm in db.GetProfilePermissions() 
            where pi.ChildId == pm.ChildId 
            select pm) 
       } 

今、私はメッセージを取得:

非サポート例外:LINQはエンティティにメソッド「System.Linq.IQueryable`1 [PublicationSystem.Model.ViewModels.ProfilePermissionを認識しません。 ] GetProfilePermissions(PublicationSystem.Model.IMkpContext) 'メソッドであり、このメソッドをストア式に変換することはできません。

なぜサブクエリは一方向で、他のクエリでは機能しませんか?私はpermsがいずれかの方法でIQueryable<>として終わったと思った。

+2

問題と解決策を説明している[ここ](のhttp:// WWW。 albahari.com/nutshell/linqkit.aspx) –

+0

私は通常次のように使います:public static object GetProfilePermissions – jdweng

答えて

3

違いは、あなたが拡張メソッドを使用した場所では実行されず、別の式(あなたの場合はSelect)の一部になります。つまり、として認識されないメソッドに記憶されます。 EFクエリプロバイダ。

あなたは確かにいくつかのトップレベルにJoinまたはGroupJoinなどのクエリ構文を拡張メソッドを使用している場合は、それが動作します。または、クエリの外にコールを移動して、その結果を変数に格納することができます。

例えば、あなたのケースでは、以下が動作します:

var results = 
    from pi in db.AnotherTable 
    where pi.IsActive 
    join pm in db.GetProfilePermissions() on pi.ChildId equals pm.ChildId into permissions 
    select new MyViewModel 
    { 
     KeyId = pi.Id, 
     Permissions = permissions 
    }; 

をだけでなく、このよう:

var permissions = db.GetProfilePermissions(); 
var results = 
    from pi in db.AnotherTable 
    where pi.IsActive 
    select new MyViewModel 
    { 
     KeyId = pi.Id, 
     Permissions = (from pm in permissions 
         where pi.ChildId == pm.ChildId 
         select pm) 
    }; 
関連する問題