我有一个问题,就是按照我的意愿将LINQ查询输出。我不确定我采取了正确的方法。
我有两张表Contacts
和Permissions
,我执行 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
。
我不希望有重复的联系人,我只对第一个联系人权限记录感兴趣。像这样:
所以我假设我需要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的限制。
任何建议都将不胜感激。
答案 0 :(得分:1)
我个人认为你想要实现的目标不是通过LINQ对MySQL来实现的。在原始T-SQL中的MS SQL中可以通过定义表达式并将RANK()列附加到它然后对该表达式进行查询来实现。
我觉得您的可用解决方案是:
了解如何使用原生方言中的原始SQL编写此查询。 Lightspeed将允许您执行原始SQL,它甚至(返回足够的列)将自定义查询重新水化为实体(但我不认为这就是您在这种情况下所追求的)。
放弃在数据库中有效减少“重复”。将重复项放入内存中,然后使用LINQ查询将它们减少到内存中,以查找您获取的IEnumerable集。
更改数据库体系结构,以便您可以进行更简单的查询。有时候在这样的情况下,我会在Contact表上找到一个列,例如“MostSignificantPermssion”。这有很多好处:
选项!
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结果。只要尝试一下,你的问题就会得到解决。