3

我正在与一位同事一起工作,我们正在尝试使用 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 中实现等价的小于 (<)?

ON (t1.ResourceName = t2.ResourceName AND t1.AccountId < t2.AccountId)

任何人都可以请告知这是否可能,或者我们是否在吠叫错误的树?我们试图使初始查询尽可能简单,希望它能使等效的 LinqToEntities 查询更容易构建。

笔记:

AccountId不是唯一的。我们Identity Id在桌子上有一列LocalResourceString。然而,两者都有一个独特的AccountId约束ResourceName

4

2 回答 2

4

<EDIT> 看起来您真正想要做的是选择AccountId每个ResourceName. 如果我们假设它AccountId是唯一的,那么:

localeStringResource =
    from e1 in localeStringResource
    group e1 by e1.ResourceName into grp
    select grp.Max(e => e.AccountID);

</编辑>

您在这里有一个左外连接,因此您的 LINQ 将需要一个GroupJoin--构造SelectMany。并且被重构为相等,但您可以稍后在 : 之前添加条件的其余部分:DefaultIfEmptyJoinGroupJoinDefaultIfEmpty

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);
于 2012-10-08T14:26:53.023 回答
-1

尝试使用 ANSI-82 语法将连接条件放在 where 子句中:

localeStringResource = from e1 in localeStringResource
                       from e2 in localeStringResource
                       where e1.ResourceName = e2.ResourceName &&
                            e1.AccountId < e2.AccountId
                       select e1;
于 2012-10-08T14:17:30.383 回答