多个左连接和动态在哪里

时间:2013-12-20 01:32:24

标签: c# linq entity-framework

我假装要为产品构建搜索页面 Whit将表单变量倍增并将它们集成到此查询中。 动态..在像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);
            }

尝试 - &gt;我最接近的方法 - 更新

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

在左连接之前 - &gt; “来自tpJ in tpjoin.DefaultIfEmpty()” 没有错误...... 如果我去了“在db.ProductoAtributo中加入Pa”的地方 - &gt;在db.ProductoAtributo.Where中加入Pa(productoAtributoWhere) 没有错误..但是,t-sql查询返回3寄存器vs 26 linq

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

希望你能帮帮我.. 问候

这是没有左边的原始查询加入UPDATED

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();

2 个答案:

答案 0 :(得分:1)

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

首先:将谓词类型从Expression<Func<ProductoAtributo, bool>>更改为Func<ProductoAtributo, bool>

OR

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

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

答案 1 :(得分:1)

我安装了Linqer ...将t-sql转换为linq附加bin文件夹项目,并连接到sql server ...生成edml atuotmatically ..之后我得到了正确的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();