2

ParentId 列を持つ「Menu」テーブルがあります。私のLINQクエリはすぐ下にあります。

    public IEnumerable<MenuTableObject> GetMenus ( int? parentId ) {
        var result = ( from m in _db.Menus
                       join ml in _db.MenuLanguages on m.Id equals ml.MenuId
                       join l in _db.Languages on ml.LanguageId equals l.Id
                       where l.Code == Thread.CurrentThread.CurrentCulture.Name
                             && m.ParentId == ( parentId.HasValue ? parentId : null )
                       select new MenuTableObject {
                           Action = m.Action,
                           Controller = m.Controller,
                           Id = m.Id,
                           Title = ml.Title,
                           SubMenus = this.GetMenus( m.Id )
                       } );

        return result;
    }

そして、これが MenuTableObject クラスです。

public class MenuTableObject {
    public int Id { get; set; }
    public string Title { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public IEnumerable<MenuTableObject> SubMenus { get; set; }
}

以下は例外です。

LINQ to Entities does not recognize the method 'System.Collections.Generic.IEnumerable`1[IstanbulHairCenter.Data.Service.MenuTableObject] GetMenus(System.Nullable`1[System.Int32])' method, and this method cannot be translated into a store expression.

この問題を乗り越えるにはどうすればいいですか?

4

2 に答える 2

0

経験則として、任意の EFIQueryableクエリでカスタム関数を使用することはできません (拡張ポイントがあるかもしれませんが、確かではありません)。

IQueryableクエリは式ツリーであり、func ではありません ( がではなくIQueryable Where()を取ることに注意してください)。ツリーは特定の実装 (この場合はエンティティ フレームワーク) によって分析され、SQL 文字列にマップされます。Expression<Func<T, bool>>Func<T, bool>

各マッピングは、実装者が明示的に作成する必要があります。EF は、メソッドで何をすべきかわからないことを伝えていますGetMenus()(つまり、-> SQL からのマッピングGetMenus()が存在しません)。

これを回避するには、関連するすべてのデータを DB から取り出してから、LINQ to Object ではなく LINQ to Entities を使用してクエリを実行します。

再帰は本当の原因ではありません。最初の再帰が呼び出される前に、エンティティで使用する必要がありますToList()(またはAsEnumerable()、それについてはわかりません) 。GetMenus()または、StoredProc などを記述して、コンテキストまたはDbSet.

于 2012-07-18T00:18:53.547 に答える
0

EF はメソッドを SQL にSubMenus変換できないため、LINQ クエリの外で結果をループして入力する必要があります。GetMenus

public IEnumerable<MenuTableObject> GetMenus ( int? parentId ) {
    var result = ( from m in _db.Menus
                   join ml in _db.MenuLanguages on m.Id equals ml.MenuId
                   join l in _db.Languages on ml.LanguageId equals l.Id
                   where l.Code == Thread.CurrentThread.CurrentCulture.Name
                         && m.ParentId == ( parentId.HasValue ? parentId : null )
                   select new MenuTableObject {
                       Action = m.Action,
                       Controller = m.Controller,
                       Id = m.Id,
                       Title = ml.Title
                   } ).ToList();

    foreach(var menu in result)
    {
        menu.SubMenus = this.GetMenus(menu.Id);
    }

    return result;
}
于 2012-07-18T00:19:49.063 に答える