1. ホーム
  2. c#

[解決済み] メソッドをストア式に変換できない

2023-04-02 05:12:32

質問

このコードはLINQ to SQLで動作するのを見ましたが、Entity Frameworkを使用すると、このエラーがスローされます。

LINQ to Entities は 'System.Linq.IQueryable'1[MyProject.Models.CommunityFeatures] GetCommunityFeatures()' メソッドを認識せず、このメソッドはストア式に変換できません`。

リポジトリコードはこれです。

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates
           let AllCommFeat = GetCommunityFeatures()
           let AllHomeFeat = GetHomeFeatures()
           select new Models.Estate
                      {
                                EstateId = e.EstateId,
                                AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
                                AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
                      };
}

public IQueryable<Models.CommunityFeatures> GetCommunityFeatures()
{
    return from f in entity.CommunityFeatures
           select new CommunityFeatures
                      {
                          Name = f.CommunityFeature1,
                          CommunityFeatureId = f.CommunityFeatureId
                      };
}

public IQueryable<Models.HomeFeatures> GetHomeFeatures()
{
    return from f in entity.HomeFeatures
           select new HomeFeatures()
           {
               Name = f.HomeFeature1,
               HomeFeatureId = f.HomeFeatureId
           };
}

LazyList は IQueryable の機能を拡張したリストです。

なぜこのエラーが発生するのか、どなたか説明していただけませんか?

どのように解決するのですか?

理由は? 設計上 LINQ to Entities では、LINQ のクエリ式全体がサーバーのクエリに変換される必要があります。クエリが翻訳される前に、いくつかの関連性のない部分式 (クエリ内の式でサーバーからの結果に依存しないもの) のみがクライアントで評価されます。この場合の GetHomeFeatures() のような、既知の翻訳を持たない任意のメソッド呼び出しはサポートされていません。

より具体的に言うと、LINQ to Entitiesは以下のものだけをサポートします。 パラメータレスコンストラクタ イニシャライザ .



解答です。 したがって、この例外を克服するためには、サブクエリをメインクエリにマージする必要があります。 GetCommunityFeatures() GetHomeFeatures() のように、LINQクエリ内から直接メソッドを呼び出すのではなく、LINQクエリからメソッドを呼び出します。また、新しいインスタンスをインスタンス化しようとした行に問題があります。 LazyList の新しいインスタンスをインスタンス化しようとしている行の問題です。 LINQ to SQL . そのための解決策は、LINQ クエリのクライアント評価 (LINQ to Objects) に切り替えることです。これには AsEnumerable メソッドを使用して、LazyList コンストラクタを呼び出す前に、LINQ to Entities クエリで使用することができます。



このようなものが動作するはずです。

public IQueryable<Models.Estate> GetEstates()
{
    return from e in entity.Estates.AsEnumerable()
       let AllCommFeat = from f in entity.CommunityFeatures
                         select new CommunityFeatures {
                             Name = f.CommunityFeature1,
                             CommunityFeatureId = f.CommunityFeatureId
                         },
       let AllHomeFeat = from f in entity.HomeFeatures
                         select new HomeFeatures() {
                             Name = f.HomeFeature1,
                             HomeFeatureId = f.HomeFeatureId
                         },
       select new Models.Estate {
            EstateId = e.EstateId,
            AllHomeFeatures = new LazyList<HomeFeatures>(AllHomeFeat),
            AllCommunityFeatures = new LazyList<CommunityFeatures>(AllCommFeat)
       };
}



もっと詳しく をご覧ください。 LINQ to Entities、何がサポートされていないのですか? をご覧ください。 また、以下をチェックしてください。 LINQ to Entities、サポートされないものの回避方法 にて、可能な解決策について詳しく説明しています。 (どちらのリンクも、オリジナルの Web サイトがダウンしているため、キャッシュされたバージョンです)