我正在与同事合作,我们正尝试使用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;
基本上它只是说我们返回最高的AccountIds,其中有多个匹配的ResourceName。到目前为止我们已经得到了这个......
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中实现等于小于(&lt;)的等价物?
ON (t1.ResourceName = t2.ResourceName AND t1.AccountId < t2.AccountId)
有人可以告诉我这是否可能,或者我们是否正在咆哮错误的树?我们试图使初始查询尽可能简单,希望它能使等效的LinqToEntities查询更容易构建。
注意:
AccountId
不是唯一的。我们在Identity
表上有一个Id
LocalResourceString
列。但是,AccountId
和ResourceName
答案 0 :(得分:4)
&LT;编辑&gt;
看起来您真正想要做的是选择每个AccountId
具有最大ResourceName
的记录。如果我们假设AccountId
是唯一的,那么:
localeStringResource =
from e1 in localeStringResource
group e1 by e1.ResourceName into grp
select grp.Max(e => e.AccountID);
&LT; /编辑&gt;
这里有一个左外连接,所以你的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);
答案 1 :(得分:-1)
尝试使用ANSI-82语法将连接条件放在where子句中:
localeStringResource = from e1 in localeStringResource
from e2 in localeStringResource
where e1.ResourceName = e2.ResourceName &&
e1.AccountId < e2.AccountId
select e1;