【发布时间】:2010-11-15 11:27:25
【问题描述】:
左连接 LINQ 并使用按位比较。
我有一个问题可以描述为(感谢 David B 澄清这一点): 目标是从左表中为每个 OID 返回 1 行,其中左表中的记录计数等于右表中匹配行的计数。在 FLAGS 中为一行设置 OID、RID 和 FLAG 时,记录匹配。
我们正在比较的对象具有以下结构:
public class Roads : List<Road>{}
public class Road
{
public int RID;
public int OID;
public int Check = 1;
public long Flag;
}
public class Cars : List<Car> { }
public class Car
{
public int RID;
public int OID;
public long Flags;
}
用以下数据填充的对象。
Roads rs = new Roads();
Cars cs = new Cars();
Car c = new Car();
c.OID = 1;
c.RID = 1;
c.Flags = 31; // 11111
cs.Add(c);
c = new Car();
c.OID = 1;
c.RID = 2;
c.Flags = 31; //11111
cs.Add(c);
c = new Car();
c.OID = 1;
c.RID = 3;
c.Flags = 4; //00100
cs.Add(c);
Road r = new Road();
r.OID = 1;
r.RID = 1;
r.Flag = 8; //00010
rs.Add(r);
r = new Road();
r.OID = 1;
r.RID = 2;
r.Flag = 2; //01000
rs.Add(r);
r = new Road();
r.OID = 1;
r.RID = 3;
r.Flag = 4; //01000
rs.Add(r);
// r = new Road();
// r.OID = 1;
// r.RID = 3;
// r.Flag = 16; //00001
// rs.Add(r);
要查看是否设置了标志,请进行按位比较,即 cs[0].Flags && rs[0].Flag > 0 为 TRUE,cs[0].Flags & rs[0].Flag = 0是假的
我有这个通用查询,它将获取 cs 中的 OID 计数 = rs 中匹配 OID 的计数的行。我现在需要一个修改后的查询,其中应用了其余规则。我们检查Flag是否在特定行匹配的Flag中。
var carLookup = cs.ToLookup(cb => c.OID);
var roadLookup = rs.ToLookup(rb => r.OID);
var results1 = from x in carLookup
let carCount = x.Count()
let roadCount = roadLookup[x.Key].Count()
where carCount == roadCount
select new { OID = x.Key, CarCount = carCount, RoadCount = roadCount };
如何扩展它以应用其他过滤条件?我正在苦苦挣扎的是在我需要它们来构建适当的过滤条件的地方提供可用的列。比如我需要比较Flags && Flag。但是我如何才能访问 Flag 和 Flags 来做额外的过滤呢?
展开。我主要使用 TSQL,所以我试图模仿一个可以轻松应用于 TSQL 的逻辑流程。如果我使用 TSQL 执行此操作,它将如下所示(注意 0 的特殊情况):
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
AND (CS.FLAGS & RS.FLAG > 0
OR (CS.FLAGS=0 AND RS.FLAG=0))
GROUP BY cs.OID
HAVING Count(cs.OID) = Sum(RS.Check)
使用该语句和上面的数据,结果将是 1、3、3。
如果我要注释最后添加到 Roads,并取消注释下一行,将 Flag 更改为 16,那么结果将是: 无效的 如果您需要更多信息,请发表评论。
【问题讨论】:
标签: linq linq-to-objects