メソッドをストア式に変換できません


89

このコードが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の機能を拡張するリストです。

誰かがこのエラーが発生する理由を説明できますか?

回答:


115

理由: 設計上、LINQ to Entitiesでは、LINQクエリ式全体をサーバークエリに変換する必要があります。クエリが変換される前にクライアントで評価されるのは、少数の無相関の部分式(サーバー内の結果に依存しないクエリ内の式)だけです。この場合のGetHomeFeatures()のように、既知の変換がない任意のメソッド呼び出しはサポートされていません。
具体的には、LINQ to Entitiesはパラメーターなしのコンストラクター初期化子のみをサポートします。

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

このようなものがうまくいくはずです:

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サイトがダウンしているため、どちらのリンクもキャッシュされたバージョンです)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.