c# - 在 SelectMany LINQ to Entity Framework 中使用 PredicateBuilder

标签 c# linq entity-framework-6 predicatebuilder linqkit

第一次在stackoverflow上写到这里。

我想在带有 SelectMany 的 LINQ 查询中使用 PredicateBuilder。

我输入我的代码

public async Task<List<Articolo>> OttieniElencoArticoliFiltratoComplessoAsync
    (ExpressionStarter<Articolo> predicateArticolo,
        ExpressionStarter<ArticoloFornitore> predicateFornitore,
        ExpressionStarter<Categoria> predicateCategoria,
        ExpressionStarter<Magazzino> predicateMagazzino,
        ExpressionStarter<PrezzoVendita> predicatePrezzoVendita)
    {
        using (var database = DatabaseContext.NuovoDatabase())
        {
            var query = database.Articoli.AsExpandable();

            if (predicateArticolo != null)
            {
                query = query.Where(predicateArticolo);
            }

            if (predicateFornitore != null)
            {
                query = query.AsExpandable().SelectMany(a => a.ElencoArticoliFornitore.Where(predicateFornitore)).Select(fornitore => fornitore.Articolo);
            }

            if (predicateMagazzino != null)
            {
                query = query.AsExpandable()
                    .SelectMany(articolo => articolo.ElencoMagazzino.Where(predicateMagazzino))
                    .Select(magazzino => magazzino.Articolo);
            }

            if (predicatePrezzoVendita != null)
            {
                query = query.AsExpandable().SelectMany(articolo =>
                    articolo.ElencoPrezzoVendita.Where(predicatePrezzoVendita).Select(vendita => vendita.Articolo));
            }

            if (predicateCategoria != null)
            {
                query = query.AsExpandable()
                    .SelectMany(articolo => articolo.ElencoCategorie.Where(predicateCategoria))
                    .Select(categoria => categoria.Articolo);
            }

            return await query.ToListAsync();
        }
    }

我这样创建谓词

        private ExpressionStarter<ArticoloFornitore> PredicateFornitore()
    {
        var ritornaNull = true;
        var predicate = PredicateBuilder.New<ArticoloFornitore>();
        if (IsEnabledFiltroFornitore && FornitoreSelezionato != null)
        {
            ritornaNull = false;
            predicate = predicate.And(fornitore => fornitore.IdFornitore == FornitoreSelezionato.IdFornitore);
        }
        return ritornaNull ? null : predicate;
    }

    private ExpressionStarter<Categoria> PredicateCategoria()
    {
        var ritornaNull = true;
        var predicate = PredicateBuilder.New<Categoria>();
        if (IsEnabledCategoriaLivello1 && CategoriaLivello1Selezionata != null)
        {
            ritornaNull = false;
            predicate = predicate.And(categoria =>
                categoria.IdCategoriaLv1 == CategoriaLivello1Selezionata.IdCategoriaLv1);
        }

        if (IsEnabledCategoriaLivello2 && CategoriaLivello2Selezionata != null)
        {
            ritornaNull = false;
            predicate = predicate.And(categoria =>
                categoria.IdCategoriaLv2 == CategoriaLivello2Selezionata.IdCategoriaLv2);
        }

        if (IsEnabledCategoriaLivello3 && CategoriaLivello3Selezionata != null)
        {
            ritornaNull = false;
            predicate = predicate.And(categoria =>
                categoria.IdCategoriaLv3 == CategoriaLivello3Selezionata.IdCategoriaLv3);
        }

        if (IsEnabledCategoriaLivello4 && CategoriaLivello4Selezionata != null)
        {
            ritornaNull = false;
            predicate = predicate.And(categoria =>
                categoria.IdCategoriaLv4 == CategoriaLivello4Selezionata.IdCategoriaLv4);
        }

        if (IsEnabledCategoriaLivello5 && CategoriaLivello5Selezionata != null)
        {
            ritornaNull = false;
            predicate = predicate.And(categoria =>
                categoria.IdCategoriaLv5 == CategoriaLivello5Selezionata.IdCategoriaLv5);
        }
        return ritornaNull ? null : predicate;
    }

我在使用固定数据而不是 PredicateBuilder 的 LINQPAD 上尝试了此方法,并且查询有效。 但是使用 PredicateBuilder,我得到了 .NET Framework 数据提供程序错误 1025。

我该如何解决?我希望能够创建一个从界面获取参数并返回结果的动态查询。

我希望你能帮助我。

最佳答案

EntityFramework 要求您的谓词为 Expression<Func<T, bool>>而不是 Func<T, bool> .这就是IQueryable.ToExpandable()做。但是,您的实体对象,例如 articolo.ElencoPrezzoVendita是虚拟的 ICollection对象,因此谓词减少为 Func<T, bool>这与 EF 不兼容。

它并没有完全脱口而出,但你可以用数据库尝试这样的事情(我不知道你的对象的结构)以确保 Expression被使用。

if (predicatePrezzoVendita != null)
{
    query = query.AsExpandable()
        .SelectMany(articolo =>
            database.ElencoPrezzoVendita
                .Where(x => articolo.ForeignKeyID == x.ID)
                .AsExpandable()
                .Where(predicatePrezzoVendita)
                .Select(vendita => vendita.Articolo));
}

关于c# - 在 SelectMany LINQ to Entity Framework 中使用 PredicateBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49316071/

相关文章:

c# - 如何从分组元素创建字典?

c# - LINQ to Entities 无法识别方法 'System.Object GetValue(...)'

.net - 一对一的可选关系,两端可选且两个 FK

c# - ASP.NET MVC + LINQ 异常

c# - Entity Framework .First() 缓存查询数据

c# - Activator.CreateInstance 上的 TargetInvocationException

c# - XML 注释 - 是否应该看到引用是完全合格的?

c# - 如何在桌面应用程序中使用 OneDrive 的 api 并记住权限?

c# - Entity Framework 代码优先 : Using a database that doesn't need to be separately installed?

c# - 如何使用 linq 仅对一列进行分组