Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.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
C# LINQ联合vs SQL联合_C#_Sql Server_Entity Framework_Linq - Fatal编程技术网

C# LINQ联合vs SQL联合

C# LINQ联合vs SQL联合,c#,sql-server,entity-framework,linq,C#,Sql Server,Entity Framework,Linq,我在用户和用户项目之间建立关系UserProjects.UserId对Users.UserId的引用 我想查找位于UserProjects中且UserProject具有UsreProjects.projectd==4的用户。然后将其余用户合并到此表 事实上,我想更改User的一些属性,UserProject=4 在MSSQL中,为了测试我有下面的查询 Select U.UserId from Users U Join UserProjects UP On U.UserId = up.UserI

我在
用户
用户项目
之间建立关系
UserProjects.UserId
Users.UserId的引用

我想查找位于
UserProjects
中且
UserProject
具有
UsreProjects.projectd==4的用户。然后将其余用户合并到此表

事实上,我想更改User的一些属性,
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;
当工会不允许复制时,情况如何


再见,谢谢

解释了
SQL联合
(执行隐式
DISTINCT
)和
LINQ联合
(需要显式
DISTINCT()
)之间的行为差异


因此,对于您的特定情况,只需对查询应用
Distinct()

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

项目4中的用户(或变量projectd的任何值)将在结果中出现两次,一次是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;
LINQ联合vs SQL联合

它们是等价的

但是现在使用相同的查询来更改属性会导致比我拥有更多的用户

 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;
这与查询不一样。在第一个(SQL)查询中,您只选择(包括)一个字段(
UserId
),而在第二个(LINQ)查询中,您包括两个字段,其中一个字段肯定是不同的。由于
Union
使用所有包含的字段作为判断项目是否唯一的标准,因此第二次查询返回更多项目是正常的

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


你提供的链接根本无法解释差异。它讨论的是内存中的linq,而不是ef或l2s。只要对象具有可比性和相等性,linq并集就会产生唯一的对象。您正在讨论的对象是ProjectUsersDTO。我认为您需要在这个对象上实现一个IEquatable接口,以便联盟按照您的意愿工作。此外,由于“alreadyInProject”[sic]属性不相同,因此您的值集略有不同。如果IEquatable实现忽略此属性,则这无关紧要。您正在使用IEnumerable.Union,因为您在该Union之前投影到DTO。如果希望数据库执行distinct,则需要将对DTO的投影推迟到union之后。因此,在两个查询中都投影到一个匿名类型,然后是union,然后添加一个AsEnumerable()调用,然后投影到DTO,然后执行ToList()。@Maarten我正要添加它。