简体   繁体   English

在实体框架查询中组合内部联接和左联接

[英]Combine inner join and left join in Entity Framework query

I have 3 classes / tables: Car , User and UserVote (which is a bridging table between the other two). 我有3个类/表: CarUserUserVote (这是其他两个之间的桥接表)。

For example: 例如:

Car (id / name):
1 / Ford Focus
2 / Honda Civic
3 / Citroen C2

User (id / ignoreUser):
1 / false
2 / true
3 / false

UserVote (UserId / CarId)
1 / 2
1 / 3
2 / 1
3 / 2

I have a method which gets the top x cars based on the number of votes. 我有一种方法,可以根据票数获得前x辆汽车。

public IQueryable<Car> GetTopCars(int count)
{
    return context.Car
        .Include(car => car.UserVote)
        .Where(car => car.UserVote.Count > 0)
        .OrderByDescending(car => car.UserVote.Count)
        .Take(count);
}

This code only looks at the Cars and UserVote table and doesn't look at the ignoreUser field on User. 此代码仅查看Cars and UserVote表,而不查看User上的ignoreUser字段。 I am trying to update my Entity Framework code to join to the User table, but I'm not having any success. 我正在尝试更新我的实体框架代码以加入到User表,但是没有成功。 Ultimately I am looking to get a list of Cars ordered by the number of UserVotes, excluding those with IgnoreUser set to true. 最终,我希望获得按UserVote数量排序的汽车列表,但IgnoreUser设置为true的汽车除外。 In the above example, I would like the method to return IQueryable in the correct order (Honda Civic then Citroen C2). 在上面的示例中,我希望该方法以正确的顺序返回IQueryable(本田Civic,然后是雪铁龙C2)。

I think I want to take Cars and then left join this to User inner joined with UserVote? 我想我想乘坐Cars,然后将其加入与UserVote连接的User inner吗? Is this possible with Entity Framework? 使用实体框架可以做到吗?

This question follows on from the advice given in a comment to a previous question . 这个问题源自对前一个问题的评论中给出的建议。

If you have an User navigation property in your UserVote entity then you query could be this way: 如果您的UserVote实体中具有User导航属性,则可以通过以下方式查询:

public IQueryable<Car> GetTopCars(int count)
{
    return (from c in context.Car
            let userVotes=car.UserVote.Where(uv=>!uv.User.IgnoreUser).Count()
            where userVotes > 0
            orderby userVotes
            select c)
           .Take(count);
}

If you want to do it using just join operations then you could do this: 如果您只想使用join操作来做到这一点,那么您可以这样做:

public IQueryable<Car> GetTopCars(int count)
{
    return (from c in context.Car
            let userVotes=(from uv in c.UserVotes
                           join u in context.Users on uv.UserId equals u.Id into users
                           where u=>!u.IgnoreUser
                           select u).Count()
            where userVotes > 0
            orderby userVotes
            select c
           )
           .Take(count);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM