繁体   English   中英

如何将此LINQ查询写为单个查询?

[英]How to write this LINQ query as a single query?

考虑以下代码:

var query = from groupRole in CurrentItem.MEMGroupRoles 
            select groupRole.MEMRole;
this.AvailableRoles = this.allRoles.Except(query.AsEnumerable()).ToList();

在此代码中,我采用allRoles,除了CurrentItem已经具有的那些角色。 2个问题:

  1. 这是行不通的,因为我在对象上进行比较,并且这些对象是不同的实例
  2. 我不喜欢两条线,喜欢提高。

这是我现在真正需要做的伪代码:

var queryIds = from groupRole in CurrentItem.MEMGroupRoles 
               select groupRole.MEMRole.RoleId;
this.AvailableRoles = this.allRoles.Except(where RoleId query.AsEnumerable()).ToList();

我该如何编写查询?

编辑

说明:

  1. allRoles包含MEMRole对象的列表
  2. CurrentItem.MEMGroupRoles包含MEMGroupRole对象的列表,每个MEMGroupRole包含内部的MEMRole

我想选择allRoles内的所有MEMRole对象,除了那些埋藏在CurrentItem内部的MEMRoles。 第一个代码段可以工作,但是我需要通过MEMRole.RoleId将MEMRole与MEMRole进行比较,因为它是同一数据库实体的不同实例。

如果角色对象适合通过角色ID进行标识,则可以覆盖Equals()GetHashCode() 如果不是这种情况,则可以创建一个实现IEqualityComparer<>的角色比较器类。 Except()将相等比较器作为第二个参数。

这是一个为角色ID创建查找并使用它来过滤角色的解决方案。 但是,我确实认为上述替代方案可以更好地解决您的问题。

var lookup = CurrentItem.MEMGroupRoles
        .ToLookup(groupRole => groupRole.MEMRole.RoleId);
this.AvailableRoles = this.allRoles
        .Where(role => !lookup.Contains(role.RoleId))
        .ToList();

按照您建议的方法:

var ids = CurrentItem.MEMGroupRoles.Select(g => g.MMERole.RoleId);
this.AvailableRoles = this.allRoles.Where(r => ids.All(i => i != r.RoleId));

另外,(虽然我不会走这条路),如果您必须具有单个查询,则可以附加两个角色集合( currentall ),按RoleId分组,并选择仅具有单个成员的组:

this.AvailableRoles = CurrentItem.MEMGroupRoles
    .Select(g => g.MEMRole)
    .Concat(this.allRoles)
    .GroupBy(r => r.RoleId)
    .Where(g => g.Count() == 1)
    .Select(g => g.First());

这将导致不在CurrentItem.MEMGroupRoles集合中的角色。 但是再一次,这只是...运动:)

这是LINQ to SQL吗?

如果是这样,请使用DataContext.Log属性查看传递给数据库的实际SQL,这可以帮助您诊断问题。

暂无
暂无

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

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