Linq将子查询与多列上的相同表相关联

时间:2015-01-07 23:13:10

标签: c# sql-server linq linq-to-entities

我已经查看了与相关子查询相关的其他几个问题,但我仍然不清楚如何完成我需要的工作。我正在使用Entity Framework和C#,并有一个名为STEWARDSHIP的表,其中包含以下列:

  • STEWARDSHIP_ID(主键)
  • SITE_ID
  • VISIT_DATE
  • VISIT_TYPE_ID

我需要识别SITE_ID,VISIT_DATE,VISIT_TYPE_ID的相同组合不止一次存在的情况,因为它可能表示最终用户出错的重复条目,然后我需要报告这些条目的详细信息。在SQL中,我会通过加入GROUP BY / HAVING的临时结果来实现这一点:

SELECT * FROM stewardship AS s2,
(SELECT site_id, visit_type_id, CAST(visit_date AS DATE) AS visit_date
    FROM stewardship
    GROUP BY site_id, visit_type_id, CAST(visit_date AS DATE)
    HAVING COUNT(*) > 1) AS s
WHERE s2.site_id = s.site_id
AND s2.visit_type_id = s.visit_type_id
AND CAST(s2.visit_date AS DATE) = s.visit_date

在Linq中实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

由于您对应该更高效的其他方法持开放态度,因此这里有新的SQL来获取我认为您正在追求的内容。

select distinct s1.*
from stewardship s1
    inner join stewardship s2 on 
        s1.stewardship_id <> s2.stewardship_id and
        s1.site_id = s2.site_id and
        s1.visit_type_id = s2.visit_type_id and
        cast(s1.visit_date as date) = cast(s2.visit_date as date)
order by s1.site_id, s1.visit_type_id

现在,要将其转换为LINQ,您可以使用以下语句。

var duplicates = (
    from s in Stewardships
    join s2 in Stewardships
        on new { s.Site_id, s.Visit_type_id, s.Visit_date.Date } equals new { s2.Site_id, s2.Visit_type_id, s2.Visit_date.Date }
    where s.Stewardship_id != s2.Stewardship_id
    select s)
.Distinct()
.OrderBy(s => s.Site_id)
    .ThenBy(s => s.Visit_type_id)

请注意,除了equijoin之外,你不能使用任何表达式连接,所以我必须在where表达式中放置非equijoin(确保我们的匹配不是通过PK在同一记录上)。您也可以通过Except()扩展方法使用lambdas完成此操作。

顺序依次是结果的可读性和上面的SQL语句。

我希望这有帮助!

答案 1 :(得分:0)

这与你已经拥有的相似。

from s in context.stewardships
group s by new {s.site_id, s.visit_type_id, visit_date} into g
where g.Count() > 1
select g;

这将为您提供具有相似值的管家群。你可以&#34;压扁&#34;之后使用SelectMany的那些结果,但您可能会发现它们在组中更有用。

请注意,您可能需要使用SqlFunctions或其他东西来执行与迄今为止相同的转换。