左连接LINQ并使用位比较

左连接LINQ并使用位比较,linq,linq-to-objects,Linq,Linq To Objects,左连接LINQ并使用位比较 我有一个问题可以描述为(感谢David B对此的澄清): 目标是从左表中为每个OID返回1行,其中左表中记录的计数等于右表中匹配行的计数。当OID、RID和标志在行的标志中设置时,记录匹配 我们正在比较的对象具有以下结构: public class Roads : List<Road>{} public class Road { public int RID; public int OID; public int Check = 1

左连接LINQ并使用位比较

我有一个问题可以描述为(感谢David B对此的澄清): 目标是从左表中为每个OID返回1行,其中左表中记录的计数等于右表中匹配行的计数。当OID、RID和标志在行的标志中设置时,记录匹配

我们正在比较的对象具有以下结构:

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;
}
要查看是否设置了标志,请执行位比较,即cs[0]。标志和&rs[0]。标志>0为真,cs[0]。标志和rs[0]。标志=0为假

我有一个常规查询,它将获得cs中OID的计数=rs中匹配OID的计数的行。我现在需要一个修改后的查询,其中应用了其余规则。在这里,我们检查标志是否位于特定行匹配的标志中

    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 };
我如何扩展它以应用附加的过滤条件?我正在努力解决的是,在我需要的地方有可用的列来构建适当的过滤条件。例如,我需要比较标志和标志。但是我如何才能访问Flag和Flags来进行额外的筛选呢

扩大。我主要使用TSQL,所以我尝试模拟一个可以轻松应用于TSQL的逻辑流。如果我使用TSQL执行此操作,它将如下所示(注意0的特殊情况):

有了这句话,再加上上面的数据,结果将是 一,三,三

如果我对最后一个添加到Roads的内容进行注释,并取消对下一行的注释,将标志更改为16,那么结果将是: 无效的
如果您需要更多信息,请发表评论。

我认为这应该等同于您的SQL语句,但是它没有产生您提到的结果,因为您的SQL使用了
RS.Check
,但您没有在示例代码中指定任何
Check
值(您使用了
r.OID
)。我继续添加
r.Check=1到每个
道路
对象,并能够获得您提到的结果

var query = from car in cs
            from road in rs
            where car.OID == road.OID
                && car.RID == road.RID
                && ((car.Flags & road.Flag) > 0 || (car.Flags == 0 && road.Flag == 0))
            group new { car, road } by car.OID into grouping
            let CarCount = grouping.Count()
            let RoadCount = grouping.Sum(o => o.road.Check)
            where CarCount == RoadCount
            select new { OID = grouping.Key, CarCount, RoadCount };

谢谢你的反馈。。。。对不起,在TSQL上。解决方案的唯一问题是,它总是返回与精确匹配时相同的CarCount和RoadCount计数。因此,对于上面的样本数据,结果是OID=1,CarCount=3,RoadCount=3。更改要添加的最后一条道路,使其标志为16而不是4。结果是OID=1、CarCount=2、RoadCount=2。对于此问题的真正解决方案,最后一个标志为16,OID=1,CarCount=3,RoadCount=2。(我在示例类中为Check添加了一个默认值)虽然Ahmad的解决方案不是100%,但他的解决方案能够让我对Linq有更多的了解,并了解到最终只有一条Linq语句真的没有一个固溶体。即使只使用Linq,性能也明显低于解决此问题的其他方法。
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)   
var query = from car in cs
            from road in rs
            where car.OID == road.OID
                && car.RID == road.RID
                && ((car.Flags & road.Flag) > 0 || (car.Flags == 0 && road.Flag == 0))
            group new { car, road } by car.OID into grouping
            let CarCount = grouping.Count()
            let RoadCount = grouping.Sum(o => o.road.Check)
            where CarCount == RoadCount
            select new { OID = grouping.Key, CarCount, RoadCount };