Entity Framework 中的自连接

3
我希望在实体框架中拥有以下类型的查询。
SELECT  c2.* 
FROM    Category c1 INNER JOIN Category c2
ON      c1.CategoryID = c2.ParentCategoryID
WHERE   c1.ParentCategoryID is NULL

如何在Entity Framework中完成上述工作...
3个回答

11

好吧,我对EF不是很了解,但那看起来有点像:

var query = from c1 in db.Category
            where c1.ParentCategoryId == null
            join c2 in db.Category on c1.CategoryId equals c2.ParentCategoryId
            select c2;

3
@Waheed:我不知道你的意思 - 你应该可以在EF中使用那个确切的查询。 - Jon Skeet
你好,我已将其更改为返回List<Category>类型的catergoyList,然后它说需要进行强制转换。如何将var强制转换为List<Category>对象? - SHEKHAR SHETE
@SHEKHARSHETE:你不需要进行强制类型转换,因为结果并不是一个List<Category> - 你应该调用ToList()方法,例如return query.ToList(); - Jon Skeet
抱歉,我指的是流畅的语法。 - Ellesedil
@Ellesedil 嗯,那肯定不会改变 OP 是否能够与 EF 一起使用。 - Jon Skeet
显示剩余2条评论

2

仅为了整理一下,以下内容更加优美,且具有相同的功能:

var query = from c1 in db.Category
            from c2 in db.Category
            where c1.ParentCategoryId == null
            where c1.CategoryId == c2.ParentCategoryId
            select c2;

1

在EF 4.0+中,LEFT JOIN语法略有不同,并呈现出一个疯狂的怪癖:

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 中捕获此查询的执行,您将看到它确实执行了一个 LEFT OUTER JOIN。然而,如果您在 Linq-to-Entity 查询中有多个 LEFT JOIN(“Group Join”)子句,则我发现自连接子句可能会作为 INNER JOIN 执行 - 即使使用了以上语法!

解决方法是什么?尽管听起来很疯狂并且根据微软的说法是错误的,但我通过更改联接子句的顺序解决了这个问题。如果自引用的 LEFT JOIN 子句是第一个 Linq Group Join,则 SQL Profiler 报告 INNER JOIN。如果自引用的 LEFT JOIN 子句是最后一个 Linq Group Join,则 SQL Profiler 报告 LEFT JOIN。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接