以下TSQL提供了一个如何使用SQL解决此问题的示例。目标是从左表中返回每个OID 1行,其中左表中的记录计数等于右表中匹配行的计数。
SELECT cs.OID, Count(cs.OID) AS CarCount, Sum(RS.Check) AS RoadCount
FROM Cars AS cs
LEFT JOIN Roads AS RS
ON CS.oid = RS.OID
AND cs.RID = RS.RID
GROUP BY cs.OID
HAVING Count(cs.OID) = Sum(RS.Check)
使用下面的对象设置,是否有可以构造的等效LINQ查询,或者这是不可能的?请注意为Road类的声明中检查的默认值。在下面的设置示例中,结果应为零匹配。添加一个具有适当值的道路将使其返回一个。至少那是理想的。
我遇到的问题是,这种类型的TSQL代码对于LINQ来说太复杂了。我没有找到一个明显的或非显而易见的解决方案来实现类似的行为。因此,我相信也许解决方案是停止尝试复制SQL并做一些不同的事情。由于LINQ经验不足,我不知道从哪里开始。
public class Roads : List<Road>{}
public class Road
{
public int RID;
public int OID;
public int check = 1;
}
public class Cars : List<Car> { }
public class Car
{
public int RID;
public int OID;
}
private void CheckCheck()
{
Roads rs = new Roads();
Cars cs = new Cars();
Car c = new Car();
c.OID = 1;
c.RID = 1;
cs.Add(c);
c = new Car();
c.OID = 1;
c.RID = 2;
cs.Add(c);
c = new Car();
c.OID = 1;
c.RID = 3;
cs.Add(c);
Road r = new Road();
r.OID = 1;
r.RID = 1;
rs.Add(r);
r = new Road();
r.OID = 1;
r.RID = 2;
rs.Add(r);
// Results should be :
// OID where Count of OID from C = Count of OID from R
}
答案 0 :(得分:2)
COUNT(cs.OID)
说它正在计算汽车,但事实并非如此。你的意思可能是COUNT(DISTINCT cs.OID)
这是一个字面翻译:
from c in Cars
join r in Roads on new {c.OID, c.RID} equals new {r.OID, r.RID}
group new {Car = c, Road = r} by c.OID into g
let carCount = g.Count() //did you mean g.Select(x => x.Car.OID).Distinct().Count()
let roadCount = g.Sum(x => x.Road.Check)
where carCount = roadCount
select new {OID = g.Key, CarCount = carCount, RoadCount = roadCount}
目标是从左表中每个OID返回1行,其中左表中的记录计数等于右表中匹配行的计数。
根据这个描述,我写道:
var carLookup = Cars.ToLookup(c => c.OID);
var roadLookup = Roads.ToLookup(r => r.OID);
from x in carLookup
let carCount = x.Count()
let roadCount = roadLookup[x.Key].Count()
where carCount = roadCount
select new {OID = g.Key, CarCount = carCount, RoadCount = roadCount}
答案 1 :(得分:0)
我不确定我是否完全理解所期望的结果是什么,但这是我拍摄的结果。 LINQ并不一定需要check
字段,因为除了计数之外它不起任何作用。
我误解了连接的重要性以及HAVING
子句对查询的作用。它现在回到原来的TSQL版本,但改变了RoadCount
计算。我相信这就是你要求的。
var results = from Car in cs
join road in rs
on new { Car.OID, Car.RID } equals new { road.OID, road.RID }
into Roads
group roads by Car.OID into cars
let CarCount = cars.Count()
let RoadCount = cars.Sum(roads => roads.Count())
where CarCount == RoadCount
select new
{
OID = cars.Key,
CarCount,
RoadCount
};