web-dev-qa-db-ja.com

EFコア3 X.CONTAINS()XがICOLELCECTION

次のデータ層のセットアップがあります。

public class Repository : IRepository {

    private readonly MyDbContext _dbContext;

        public List<Meter> Search(Expression<Func<Meter,bool>> criteria)
            IQueryable<Meter> results = _dbContext.Meters;
            return results.Where(criteria).ToList();
        }
    }
}

... from a client class:

IRepository _repository;

public void ClientMethod () {

    ICollection<int> ids = new List<int>() {1, 2, 3);
    var results = _repository.Search(c=> ids.Contains(c.Id)); // This throws exception

}
 _

これにより、例外が発生します。

式(source:dbset、述語:(m)=>(unhandledパラメータ:__ids_0)。contains(m.id)) 'を翻訳できませんでした。 QUERTABLE()、asAsynceNumerable()、tolistasync()のいずれかに呼び出しを挿入することで、翻訳できる形式でクエリを書き直すか、またはクライアント評価に切り替えるか、またはクライアント評価に切り替えます。

しかし、IEnumerableまたはListへのコレクション参照を変更した場合、それは機能します。

public void ClientMethod () {

    // This works
    List<int> ids = new List<int>() {1, 2, 3);
    var results = _repository.Search(c=> ids.Contains(c.Id)); 

    // This works
    IEnumerable<int> ids = new List<int>() {1, 2, 3);
    var results = _repository.Search(c=> ids.Contains(c.Id)); 
}
 _

なぜICollectionのために機能しないのですが、IEnumerable andリストのためにそうですか?私のクライアントメソッドの多くはパラメータとしてICollectionを取ります。

私はEF Core 3.0を使っていますが、私は2.1で同じ問題を抱えていたと思います、それは代わりにクライアント上でそれを評価したときに投げませんでした。

7
zola25

Ienumerable()またはlist()efcoreにキャストすると、クライアントサイドの評価を強制します。 (しかし、性能コストで動作する)

  • 「バージョン3.0の前に、エンティティフレームワークコアサポートされているクライアント評価クライアント評価」 reference
  • 3.0より前のEFCOREのバージョンも、サーバーとクライアントの評価を混在させた場合に警告を追加できます。
  • その後、EFを変更して、サーバーとクライアントの評価を混在させないようにして、偶発的なパフォーマンスの問題が起こりません。それはそれより少し複雑であるので、ここにリンクは Efcore 3.1の破断変更 * * *他のバージョンは3.0を含む左メニューナビゲーションでもここで見つけることができます。
1
CANDIMAN