如何正确分组LINQ查询?

时间:2013-11-26 11:33:39

标签: c# mysql linq lightspeed

我有一个问题,就是按照我的意愿将LINQ查询输出。我不确定我采取了正确的方法。

表:

我有两张表ContactsPermissions,我执行 LEFT OUTER JOIN

Two Tables

加入查询:

from contact in Contacts
join permission in Permissions on contact.Id equals permission.ObjectId into permissionGrp
from p in permissionGrp.DefaultIfEmpty()
where (p==null && isAllowed) || (p!=null && /* ... further conditions */))
orderby /* ... ordering removed */
select new { contact, permission = p };

这与适用的联系人的权限相匹配,如果不存在匹配权限则匹配null

Joined

所需

我不希望有重复的联系人,我只对第一个联系人权限记录感兴趣。像这样:

Desired

尝试:

所以我假设我需要Group By我的contact.Id并以某种方式选择FirstOrDefault()权限集合。

Approach

from contact in Contacts
join permission in Permissions on contact.Id equals permission.ObjectId into permissionGrp
from p in permissionGrp.DefaultIfEmpty()
where (p==null && isAllowed) || (p!=null && /* ... further conditions */))
orderby /* ... ordering removed */
group p by contact into contactPermissionsGrp
select new { contact = contactPermissionsGrp.Key, permission = contactPermissions.FirstOrDefault() };

结果:

不幸的是,这导致NotSupportedException: Specific method is not supported.。但我不确定我的方法是正确的还是LightSpeed ORM的限制。

任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:1)

回答更多问题的问题

  • 您的目标数据库中的原始SQL中是否可以查询?如果答案是否,那么你有什么希望在LINQ中复制它?

我个人认为你想要实现的目标不是通过LINQ对MySQL来实现的。在原始T-SQL中的MS SQL中可以通过定义表达式并将RANK()列附加到它然后对该表达式进行查询来实现。

我觉得您的可用解决方案是:

  1. 了解如何使用原生方言中的原始SQL编写此查询。 Lightspeed将允许您执行原始SQL,它甚至(返回足够的列)将自定义查询重新水化为实体(但我不认为这就是您在这种情况下所追求的)。

  2. 放弃在数据库中有效减少“重复”。将重复项放入内存中,然后使用LINQ查询将它们减少到内存中,以查找您获取的IEnumerable集。

  3. 更改数据库体系结构,以便您可以进行更简单的查询。有时候在这样的情况下,我会在Contact表上找到一个列,例如“MostSignificantPermssion”。这有很多好处:

    • 更简单的查询以获取联系人和ONE重要的权限记录。
    • 让其他开发人员明白其中一个权限具有特殊意义。
  4. 选项!

    附录 - 在MS SQL中实现(1)的示例

    WITH LastUsagePerPerson AS (
        SELECT 
            ULE.PersonId, 
            ULE.[Device], 
            ULE.[AppVersion], 
            ULE.[CreatedOn], 
            ROW_NUMBER() OVER(PARTITION BY ULE.PersonId ORDER BY ULE.CreatedOn DESC) AS rk
        FROM [dbo].[UsageLogEntry] ULE
        )
    
    
    SELECT 
         [FirstName]
        ,[LastName]
        ,[EmailAddress]
        ,[EmailAddressUnverified]     
        ,[MobileNumber]
        ,[MobileNumberUnverified]
        ,[LastDeviceUsed] = LastUsagePerPerson.Device
        ,[LastAppVersion] = LastUsagePerPerson.AppVersion
        ,[LastDeviceUsage] = LastUsagePerPerson.CreatedOn
        ,[LastLoggedInOn]
    
      FROM [dbo].[Person] P
        LEFT JOIN LastUsagePerPerson ON P.Id = LastUsagePerPerson.PersonId
    
    WHERE rk = 1
    
    ORDER BY [Id]
    

答案 1 :(得分:0)

我不知道Lightspeed可以或不可以。尝试简化LINQ查询 在EF我会做这样的事情。

from c in Contacts
let p = (from p in permission where p.ObjectId == c.Id select p).FirstOrDefault()
select new { ContactID = c.Id,
             Name = c.Name,
             Permission = p.PermissionId,
             Permitted = p.Permitted};

答案 2 :(得分:-2)

我已经明白你想要得到什么,我已经解决了你的问题,只需按照下面的代码我做了...

select * from contacts as a 

 left join permissions as b 

   on a.ContactId = b.ContactId

     group by a.ContactId ;

我使用你想要获得的上述代码获得了requeried结果。只要尝试一下,你的问题就会得到解决。