简体   繁体   English

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

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

Consider this code: 考虑以下代码:

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

In this code I take allRoles except those roles that CurrentItem already have. 在此代码中,我采用allRoles,除了CurrentItem已经具有的那些角色。 2 issues: 2个问题:

  1. It doesn't work because I compare on objects and those objects are different instances 这是行不通的,因为我在对象上进行比较,并且这些对象是不同的实例
  2. I don't like 2 lines and like to improve. 我不喜欢两条线,喜欢提高。

Here is pseudo-code on what I really need to do right now: 这是我现在真正需要做的伪代码:

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

How do I write query like this? 我该如何编写查询?

EDIT : 编辑

explanation: 说明:

  1. allRoles contains list of MEMRole objects allRoles包含MEMRole对象的列表
  2. CurrentItem.MEMGroupRoles contains list of MEMGroupRole objects and each MEMGroupRole contains MEMRole inside CurrentItem.MEMGroupRoles包含MEMGroupRole对象的列表,每个MEMGroupRole包含内部的MEMRole

I want to SELECT all MEMRole objects that's inside allRoles EXCEPT those MEMRoles that burries inside CurrentItem. 我想选择allRoles内的所有MEMRole对象,除了那些埋藏在CurrentItem内部的MEMRoles。 First code snippet would work, but I need to compare MEMRole to MEMRole by MEMRole.RoleId since it's a different instances of the same database entity. 第一个代码段可以工作,但是我需要通过MEMRole.RoleId将MEMRole与MEMRole进行比较,因为它是同一数据库实体的不同实例。

You could override Equals() and GetHashCode() if the role object is such that it would make sense to identify it with role id. 如果角色对象适合通过角色ID进行标识,则可以覆盖Equals()GetHashCode() If that is not the case, you could create a role comparer class that implements IEqualityComparer<> . 如果不是这种情况,则可以创建一个实现IEqualityComparer<>的角色比较器类。 Except() takes equality comparer as second parameter. Except()将相等比较器作为第二个参数。

Here is a solution that creates a lookup for role ids and uses it to filter the roles. 这是一个为角色ID创建查找并使用它来过滤角色的解决方案。 However, I do think that the alternatives above are better solutions for your problem. 但是,我确实认为上述替代方案可以更好地解决您的问题。

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

Following the approach you suggested: 按照您建议的方法:

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

Alternatively (althought I wouldn't go that road), if you must have single query, you can append both roles collections ( current and all ), group them by RoleId and pick groups that only have single member: 另外,(虽然我不会走这条路),如果您必须具有单个查询,则可以附加两个角色集合( 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());

This results in roles that weren't in CurrentItem.MEMGroupRoles collection. 这将导致不在CurrentItem.MEMGroupRoles集合中的角色。 But once again, it's just ... for sport :) 但是再一次,这只是...运动:)

Is this LINQ to SQL? 这是LINQ to SQL吗?

If so, use DataContext.Log property to see the actual SQL that is being passed to the database, which may help you diagnose the problem. 如果是这样,请使用DataContext.Log属性查看传递给数据库的实际SQL,这可以帮助您诊断问题。

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

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