4

我在让我的 LINQ 查询按我想要的方式输出时遇到问题。我不确定我是否采取了正确的方法。

表:

我有两个表ContactsPermissions我用它们执行LEFT OUTER JOIN

两张桌子

加盟查询:

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不存在匹配的权限)。

已加入

期望的

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

期望的

试图:

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

方法

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 的限制。

任何建议将不胜感激。

4

3 回答 3

1

用更多问题回答问题

  • 您的查询是否可以在您定位的数据库中使用原始 SQL 进行?如果答案是否定的,那么您有什么希望在 LINQ 中复制它?

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

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

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

  2. 放弃有效减少数据库中的“重复”。将重复项拉入内存,然后使用针对您返回的 IEnumerable 集的 LINQ 查询将它们减少到内存中。

  3. 更改您的数据库架构,以便您可以进行更简单的查询。有时在这种情况下,我会很荣幸在 Contact 表上有一列,例如“MostSignificantPermssion”。这有很多优点:

    • 更简单的查询来获取联系人和一个重要的权限记录。
    • 让其他开发人员更清楚地看到其中一项权限具有特殊意义。

选项!

附录 - 在 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]
于 2013-11-27T17:33:21.530 回答
0

我不知道 Lightspeed 能或不能。尝试在 EF 中简化您的 LINQ 查询,我会做这样的事情。

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};
于 2013-11-26T13:08:02.690 回答
-2

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

select * from contacts as a 

 left join permissions as b 

   on a.ContactId = b.ContactId

     group by a.ContactId ;

我已经使用上面你试图得到的代码得到了requeried的结果。试一试,你的问题就会得到解决。

于 2013-11-27T10:13:43.863 回答