Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linq到实体左连接_Linq_Linq To Entities_Left Join_Outer Join - Fatal编程技术网

Linq到实体左连接

Linq到实体左连接,linq,linq-to-entities,left-join,outer-join,Linq,Linq To Entities,Left Join,Outer Join,我希望在Linq to实体中实现以下目标: 获取所有没有应用程序或应用程序具有状态的查询!=4(已完成) 选择e* 来自查询enq 左外连接应用程序 关于enq.inquiryId=app.inquiryId 其中app.Status 4或app.inquiryId为空 以前是否有人在不使用DefaultIfEmpty()的情况下执行过此操作,这是Linq to实体不支持的 我正在尝试向IQueryable查询添加筛选器,如下所示: IQueryable<Enquiry> quer

我希望在Linq to实体中实现以下目标:

获取所有没有应用程序或应用程序具有状态的查询!=4(已完成)

选择e*
来自查询enq
左外连接应用程序
关于enq.inquiryId=app.inquiryId
其中app.Status 4或app.inquiryId为空
以前是否有人在不使用DefaultIfEmpty()的情况下执行过此操作,这是Linq to实体不支持的

我正在尝试向IQueryable查询添加筛选器,如下所示:

IQueryable<Enquiry> query = Context.EnquirySet; 

query = (from e in query 
         where e.Applications.DefaultIfEmpty()
                             .Where(app=>app.Status != 4).Count() >= 1 
         select e);
IQueryable query=Context.inquiryset;
query=(来自query中的e)
其中e.Applications.DefaultIfEmpty()
.Where(app=>app.Status!=4).Count()>=1
选择e);
谢谢 Mark

由于Linq处理outer的goofy(读取非标准)方式,您必须使用DefaultIfEmpty()

您要做的是将Linq To Entities查询运行到两个IEnumerable中,然后使用DefaultIfEmpty()左键连接它们。它可能看起来像:

IQueryable enq = Enquiry.Select();
IQueryable app = Application.Select();
var x = from e in enq
join a in app on e.enquiryid equals a.enquiryid
into ae
where e.Status != 4
from appEnq in ae.DefaultIfEmpty()
select e.*;
不能使用LINQto实体并不意味着不能使用原始Linq

(注意:在有人否决我之前……是的,我知道有更优雅的方法可以做到这一点。我只是想让大家理解。这是一个重要的概念,对吗?)

请执行以下操作:

IQueryable<Enquiry> query = Context.EnquirySet; 

query = (from e in query 
         where (!e.Applications.Any()) 
               || e.Applications.Any(app => app.Status != 4)
         select e);
IQueryable query=Context.inquiryset;
query=(来自query中的e)
其中(!e.Applications.Any())
||e.Applications.Any(app=>app.Status!=4)
选择e);
我认为LINQ根本没有处理SQL“goofy”中的“外部连接”问题。理解它的关键是从具有可为空属性的对象图而不是表格结果集的角度进行思考


Any()映射到SQL中的EXISTS,因此在某些情况下它比Count()更高效。

感谢大家的帮助。我最终选择了这个选项,但你的解决方案帮助我拓宽了知识面

IQueryable<Enquiry> query = Context.EnquirySet;

query = query.Except(from e in query
                     from a in e.Applications
                     where a.Status == 4
                     select e);
IQueryable query=Context.inquiryset;
query=query.Except(从query中的e开始)
来自e.Applications中的a
其中a.状态==4
选择e);

在EF 4.0+中,左连接语法有点不同,呈现出一种疯狂的怪癖:

var query = from c1 in db.Category 
        join c2 in db.Category on c1.CategoryID equals c2.ParentCategoryID  
        into ChildCategory 
        from cc in ChildCategory.DefaultIfEmpty() 
        select new CategoryObject  
        { 
            CategoryID = c1.CategoryID,  
            ChildName = cc.CategoryName 
        } 
如果您在SQL Server Profiler中捕获此查询的执行,您将看到它确实执行了左外部联接。但是,如果在Linq to Entity查询中有多个LEFT JOIN(“Group JOIN”)子句,我发现self JOIN子句实际上可以像在内部JOIN中一样执行—即使使用了上述语法


解决这个问题的决议是什么?根据MS的说法,这听起来很疯狂,也很错误,我通过改变join子句的顺序来解决这个问题。如果自引用的LEFT JOIN子句是第一个Linq组联接,则SQL探查器报告了一个内部联接。如果自引用左联接子句是最后一个LINQ组连接,SQL Prror报告了一个左联接.< /p>

另一个要考虑的事项,如果您直接引用左联接组中的WHERE子句中的任何属性(使用到语法)而不检查NULL,实体框架仍然会将左连接转换为内部连接

为了避免这种情况,请在查询的“leftJoinedExtent中的from x”部分进行如下筛选:

var y = from parent in thing
        join child in subthing on parent.ID equals child.ParentID into childTemp
        from childLJ in childTemp.Where(c => c.Visible == true).DefaultIfEmpty()
        where parent.ID == 123
        select new {
            ParentID = parent.ID,
            ChildID = childLJ.ID
        };

匿名类型中的ChildID将是一个可为空的类型,并且此类型生成的查询将是一个左联接。

当我筛选IQueryable结果以创建这样一个存储表达式时,这是否可能?您知道吗?:IQueryable query=Context.inquirySet;query=(从查询中的e开始,其中e.Applications.DefaultIfEmpty().where(app=>app.Status!=4.Count()>=1选择e);嗯,在我的例子中,这个似乎不起作用。你确定where子句是正确的吗?应用实体的状态是???感谢EF.NET4.0中包含了DefaultIfEmpty的价值。感谢Damien-期待.NET4中的EF增强。这个答案应该会得到更多的报应
var y = from parent in thing
        join child in subthing on parent.ID equals child.ParentID into childTemp
        from childLJ in childTemp.Where(c => c.Visible == true).DefaultIfEmpty()
        where parent.ID == 123
        select new {
            ParentID = parent.ID,
            ChildID = childLJ.ID
        };