【问题标题】:Multiple Left Joins and dynamic where多个左连接和动态 where
【发布时间】:2013-12-20 01:32:24
【问题描述】:

我假装为产品建立一个搜索页面 Whit 倍数形成变量并将它们集成到此查询中。 动态地.. 在独立类的 where 子句中,例如 ProductoAtributo 或其他

还有 d

T-SQL QUERY(我想要的)

SELECT 
    p.*, tpa.*, pa.*, tp.*
FROM 
    Producto p 
LEFT JOIN 
        ProductoAtributo pa ON pa.ProductoId=p.ProductoId
LEFT JOIN
        TipoProductoAtributo tpa ON tpa.AtributoId=pa.AtributoId AND tpa.TipoProductoId=p.TipoProductoId
LEFT JOIN
        TipoProducto tp ON p.TipoProductoId = tp.TipoProductoId
WHERE
        (pa.Valor = '3' AND pa.AtributoId=7) OR ( pa.Valor = '3' AND pa.AtributoId=6 )

动态位置 -- 已更新

 Func<ProductoAtributo, bool> productoAtributoWhere = Pa => true;


            string CantidadDormitorios = "3";


            if (! String.IsNullOrEmpty(CantidadDormitorios))
            {
                productoAtributoWhere = Pa => (Pa.Valor == CantidadDormitorios && Pa.AtributoId == 7) || (Pa.Valor == CantidadDormitorios && Pa.AtributoId == 6);
            }

尝试 -> 我最接近的方法 - 已更新

var producto = from P in db.Producto
                           join Tp in db.TipoProducto on P.TipoProductoId equals Tp.TipoProductoId into tpjoin
                           from TpJ in tpjoin.DefaultIfEmpty()
                           join Pa in db.ProductoAtributo on P.ProductoId equals Pa.ProductoId into pajoin
                           from PaJ in pajoin.AsQueryable<ProductoAtributo>().Where(productoAtributoWhere).DefaultIfEmpty()
                           join Tpa in db.TipoProductoAtributo on PaJ.AtributoId equals Tpa.AtributoId into tpajoin
                           from TpaJ in tpjoin.DefaultIfEmpty()
                           select new { P };
            var producto1 = producto.ToList();

错误

Error   3   'System.Collections.Generic.IEnumerable<SGI.Models.ProductoAtributo>' no contiene una definición para 'Where' y la mejor sobrecarga del método de extensión 'System.Linq.Enumerable.Where<TSource>(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,int,bool>)' tiene algunos argumentos no válidos D:\Documentos\SGI6\SGI\Areas\Cotizacion\Controllers\CotizacionController.cs 55  22  Cotizacion

Error   4   Argumento 2: no se puede convertir de 'System.Linq.Expressions.Expression<System.Func<SGI.Models.ProductoAtributo,bool>>' a 'System.Func<SGI.Models.ProductoAtributo,int,bool>'.    D:\Documentos\SGI6\SGI\Areas\Cotizacion\Controllers\CotizacionController.cs 55  35  Cotizacion

在左连接之前->“来自 tpjoin.DefaultIfEmpty() 中的 TpJ” 没有错误... 如果我将“在 db.ProductoAtributo 中加入 Pa”的位置转移到 -> 在 db.ProductoAtributo.Where(productoAtributoWhere 中加入 Pa) 也没有错误..但是 t-sql 查询返回 3 个寄存器与 26 个 linq

没有 where ...linq 和 t-sql 显示相同的结果

希望你能帮助我.. 问候

这个没有左连接的原始查询已更新

var producto = from P in db.Producto
                           join Tp in db.TipoProducto on P.TipoProductoId equals Tp.TipoProductoId
                           join Pa in db.ProductoAtributo.Where(productoAtributoWhere) on P.ProductoId equals Pa.ProductoId
                           join Tpa in db.TipoProductoAtributo on Pa.AtributoId equals Tpa.AtributoId
                           select new { P };
            var producto1 = producto.ToList();

【问题讨论】:

  • 您能否尝试在关闭 .net 本地化的情况下运行它,我无法读取您代码中的异常。我也很难弄清楚你所说的“动态”在哪里。您的Where 谓词的逻辑是什么?
  • 我认为pajoin 已经不是ProductoAtributo 集合,所以您需要更改您的表达式类型
  • 我的Where逻辑在这里暴露了..stackoverflow.com/a/1263587/493166
  • @DiegoOrtega 您在查询from TpaJ in tpjoin.DefaultIfEmpty() 中是否输入错误,可能您的意思是来自TpaJ in tpajoin.DefaultIfEmpty()
  • 你是正确的,但是现在我有 28 行..

标签: c# linq entity-framework


【解决方案1】:

您的错误说您尝试使用错误参数的调用方法,这是因为您的谓词是用于IQueryable 扩展的表达式,但是当您使用join..into clause 时,您得到的不是IQueryable,而是IEnumeration,所以对于解决我看到两条路

首先:将谓词类型从Expression&lt;Func&lt;ProductoAtributo, bool&gt;&gt; 更改为Func&lt;ProductoAtributo, bool&gt;

第二次:将分组结果转换为IQueryable,即

....
join Pa in db.ProductoAtributo on P.ProductoId equals Pa.ProductoId into pajoin
from PaJ in pajoin.AsQueryable().Where(productoAtributoWhere).DefaultIfEmpty()
....

【讨论】:

  • Grundy,感谢您的回答,错误消失了.. 但是尝试 var producto1 = producto.ToList();我得到一个无效的 Exeption 1025 内部错误 .NET Framework 数据提供程序。
  • @DiegoOrtega,对不起,我不太明白你的意思,你能再解释一下吗?
  • 我尝试使用 toList() 方法转换 linq 结果,并在过程中抛出无效异常...
  • @DiegoOrtega,哦,我看到你应用了所有路径 :-) 尝试返回 Expression 以获取 productoAtributoWhere 声明
  • Exeption 消失了..但是 T-sql(3 行)与 Linq(26 行)之间的结果不同
【解决方案2】:

我安装了 Linqer... 将 t-sql 转换为 linq 附加的 bin 文件夹项目,并连接到 sql server...自动生成 edml.. 之后我的查询得到了正确的 linq...

到目前为止,错误是把 productoAtributoWhere 放在 DefaultifEmpty() 之前,而正确的过滤器是在那之后...

感谢@Grundy ..您对ExpressionsAsQueryable 的建议非常有效。

更新代码

    Expression<Func<ProductoAtributo, bool>> productoAtributoWhere = pa => true;


                string CantidadDormitorios = "";


                if (! String.IsNullOrEmpty(CantidadDormitorios))
                {
                    productoAtributoWhere = pa => (pa.Valor == CantidadDormitorios && pa.AtributoId == 7) || (pa.Valor == CantidadDormitorios && pa.AtributoId == 6);
                }

    var producto = from p in db.Producto
                                   join pa in db.ProductoAtributo on p.ProductoId equals pa.ProductoId into pa_join
                                   from pa in pa_join.DefaultIfEmpty().AsQueryable().Where( productoAtributoWhere )
                                   join tpa in db.TipoProductoAtributo
                                         on new { pa.AtributoId, p.TipoProductoId }
                                     equals new { tpa.AtributoId, tpa.TipoProductoId } into tpa_join
                                   from tpa in tpa_join.DefaultIfEmpty()
                                   join tp in db.TipoProducto on p.TipoProductoId equals tp.TipoProductoId into tp_join
                                   from tp in tp_join.DefaultIfEmpty()
select new
                           { p };
        var producto1 = producto.ToList();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 2015-04-04
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多