我正在与一位同事合作,我们正在尝试使用 LinqToEntities( Entity Framework v4.0)重现以下 SQL 查询
SELECT t1.*
FROM [dbo].LocaleStringResource AS t1
LEFT OUTER JOIN [dbo].LocaleStringResource AS t2
ON (t1.ResourceName = t2.ResourceName AND t1.AccountId < t2.AccountId)
WHERE t2.ResourceName IS NULL;
基本上它是说只有在有多个匹配的 ResourceName 时才返回最高的 AccountId。到目前为止,我们已经得到了这个......
localeStringResource = from e1 in localeStringResource
join e2 in localeStringResource
on new { e1.ResourceName, e1.AccountId } equals new { e2.ResourceName, e2.AccountId }
where e2.ResourceName == null
select e1;
但是我们似乎还没有弄清楚如何在 LEFT OUTER JOIN 中实现等效小于 (<)?
ON (t1.ResourceName = t2.ResourceName AND t1.AccountId < t2.AccountId)
谁能告诉我这是否可行,或者我们是否找错了树?我们已尝试使初始查询尽可能简单,希望它能使等效的 LinqToEntities 查询更易于构建。
注意:
AccountId
不是唯一的。我们在 LocalResourceString
表中有一个 Identity
Id
列。但是 AccountId
和 ResourceName
最佳答案
<编辑>
看起来您真正想要做的是选择具有最大 AccountId
的记录对于每个 ResourceName
.如果我们假设 AccountId
是唯一的,那么:
localeStringResource =
from e1 in localeStringResource
group e1 by e1.ResourceName into grp
select grp.Max(e => e.AccountID);
编辑>
这里有一个左外连接,所以你的 LINQ 需要 GroupJoin
- SelectMany
- DefaultIfEmpty
构造。 Join
和 GroupJoin
被重构为相等,但您可以稍后在 DefaultIfEmpty
之前添加条件的其余部分:
localeStringResource =
from e1 in localeStringResource
join e2inner in localeStringResource
on e1.ResourceName equals e2inner.ResourceName
into grp
from e2 in grp
.Where(e => e1.AccountId < e.AccountId)
.DefaultIfEmpty()
where e2.ResourceName == null
select e1;
方法语法如下,供引用。我用了Tuple
传递数据:
localeStringResource = localeStringResource
.GroupJoin(
localeStringResource,
e1 => e1.ResourceName,
e2 => e2.ResourceName,
Tuple.Create)
.SelectMany(pair => pair.Item2
.Where(e2 => pair.Item1.AccountID < e2.AccountID)
.DefaultIfEmpty()
.Select( e2 => Tuple.Create(pair.Item1, e2)))
.Where(pair => pair.Item2.ResourceName == null)
.Select(pair => pair.Item1);
关于c# - LinqToEntities 在 LEFT OUTER JOIN 中使用小于号 (<),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12783232/