简体   繁体   English

在linq中进行外部联接并根据第二个表中的条件获取记录

[英]Outer join in linq and get records based on a condition from second table

Tables : 
Component        ComponentRights
--------------        ----------------  
ComponentId (PK)      ComponentRightsID
ComponentName         ComponentId (FK)
                      RoleId 

Lets say MyRoleId =2; 假设MyRoleId = 2;

Now, I want to get all the records from both the tables but based on one condition. 现在,我想从两个表中获取所有记录,但是基于一种条件。 If I get same record but with different RoleId, then it should take only one record where RoleId = MyRoleId. 如果我得到相同的记录,但是具有不同的RoleId,则应该只记录其中RoleId = MyRoleId的一条记录。 If no duplicates, then condition is skipped. 如果没有重复,则跳过条件。

Example:
Record 1:
------------
ComponentId = 1,
ComponentName = 'SampleComponent'
RoleId = 1

Record 2 :
-----------
ComponentId = 1,
ComponentName = 'SampleComponent'
RoleId = 2

* So In this case I should get Record 2.

Here is my sample code:



var Components = (from components in MyDB.Component
                                  join componentRights in MyDB.ComponentRights on components.ComponentId equals componentRights.ComponentId
                                  into AllComponents
                                  from allComponent in AllComponents.DefaultIfEmpty()

                                  where !(components.IsDeleted)

                                  select new ComponentRightsModel()
                                  {

                                      ComponentRightsId = (!allComponent.IsDeleted) ? (Guid?)allComponent.ComponentRightsId : null,
                                      ComponentId = components.ComponentUID,
                                      ComponentName = components.ComponentName,
                                      RoleId = allComponent.RoleId
                                  }).ToList();

I'd suggest decomposing the problem into separate statements... 我建议将问题分解成单独的语句...

var Components = (from components in MyDB.Component
                  join componentRights in MyDB.ComponentRights on components.ComponentId equals componentRights.ComponentId
                                  into AllComponents
                                  from allComponent in AllComponents.DefaultIfEmpty()

                              where !(components.IsDeleted)
                              select new ComponentRightsModel()
                              {
                                  ComponentRightsId = (!allComponent.IsDeleted) ? (Guid?)allComponent.ComponentRightsId : null,
                                  ComponentId = components.ComponentUID,
                                  ComponentName = components.ComponentName,
                                  RoleId = allComponent.RoleId
                              });
var uniqueComponetIds = Components.GroupBy(x=>x.ComponentId).Select(x=> new {ComponentId = x.Key, Count = x.Count(y=>y.RoleId)}).Where(x=>x.Count == 1).Select(x=>x.ComponentId);

var filteredDuplicates = Components.Where(x=> !uniqueComponetIds.Contains(x.ComponentId) && x.RoleId == MyRoleId);

var finalComponents = Components.Where(x=> uniqueComponetIds.Contains(x.ComponentId).Concat(filteredDuplicates);

Note that this query would also filter out records where the component is duplicated but where the duplicated collected doesn't happen to have a role with RoleId == MyRoleId. 请注意,此查询还将过滤掉记录中重复组件的记录,但其中收集的重复记录恰好不具有RoleId == MyRoleId的角色的记录。 If you want to include these as well, you can add a third statement to capture these as well. 如果还希望包括这些内容,则可以添加第三条语句来捕获它们。

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

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