LINQ Union vs SQL Union

时间:2016-02-09 15:54:20

标签: c# sql-server entity-framework linq

我与UsersUsersProjects有关系。 UserProjects.UserIdUsers.UserId

的引用

我想找到位于UserProjectsUserProject的用户UsreProjects.ProjectId == 4的用户。然后将其余用户联合到此表中。

事实上我想改变一些UserProject = 4

用户的一些属性

在MSSQL中,只是为了测试我有下面的查询

Select U.UserId 
from Users U
Join UserProjects UP
On U.UserId = up.UserId
Where up.ProjectId = 4
Union
Select U.UserId  From Users U

我没有改变任何属性。无论如何,它显示了我应该的整个用户。

但现在使用相同的查询和更改属性会产生比我更多的用户。

 var usrs = ((from users in context.Users
                             join userProj in context.UserProjects
                             on users.UserId equals userProj.UserId
                             where userProj.ProjectId == projectId
                             select new ProjectUsersDTO
                             {
                                 UserName = users.Name,
                                 Rate = users.RatePerHour,
                                 UserId = users.UserId,
                                 alreadyInProject = true
                             })
                             .Union(from users in context.Users
                                    select new ProjectUsersDTO
                                    {
                                        UserName = users.Name,
                                        Rate = users.RatePerHour,
                                        UserId = users.UserId,
                                        alreadyInProject = false
                                    }))
                               .ToList();
                    return usrs;

当UNION不允许重复时,它是如何进行的?

感谢adivce!

3 个答案:

答案 0 :(得分:2)

解释SQL UNION(执行隐式DISTINCT)和LINQ Union(需要明确的Distinct())之间的行为差​​异here

因此,对于您的具体情况,只需将Distinct()应用于您的查询。

答案 1 :(得分:2)

  

LINQ Union vs SQL Union

它们是等价的。

  

但现在使用相同的查询和更改属性会产生比我更多的用户。

不一样查询。在第一个(SQL)查询中,您选择(包括)一个字段(UserId),而在第二个(LINQ)中,您包含几个字段,其中一个肯定是不同。由于Union使用所有包含的字段作为条件是否该项是唯一的,因此第二个查询返回更多项是正常的。

话虽如此,让我们看看如何解决具体问题。看起来你根本不需要Union。通常你应该有一个导航属性,所以像这样的简单查询应该完成工作(假设导航属性被称为Projects):

var query =
    from user in context.Users
    select new ProjectUsersDTO
    {
        UserName = user.Name,
        Rate = user.RatePerHour,
        UserId = user.UserId,
        alreadyInProject = user.Projects.Any(userProj => userProj.ProjectId == projectId)
    };

var result = query.ToList();

答案 2 :(得分:0)

唯一性/无重复基于完整记录/ ProjectUsersDTO实例。

项目4中的用户(或变量projectId的任何值)将在结果中两次,一次使用alreadyInProject = true,另一次使用alreadyInProject = false。 第一个选择仅选择项目中的用户,第二个选择选择所有用户(包括项目中的用户)。它们被视为不同的记录,因为alreadyInProject的值不同,因此两个版本都将在输出中。

我不确定你想要什么,但我假设你想要一个所有用户的列表,指出他们是否在给定projectId的项目中。 您可以使用此代码

var usrs = (from users in context.Users
            join userProj in context.UserProjects
            on users.UserId equals userProj.UserId
            select new ProjectUsersDTO
            {
                UserName = users.Name,
                Rate = users.RatePerHour,
                UserId = users.UserId,
                alreadyInProject = (userProj.ProjectId == projectId)
            })
            .ToList();
return usrs;