Left Join LINQ и использование побитовых сравнений.
У меня есть проблема, которую можно описать как (спасибо David B за разъяснение этого): цель состоит в том, чтобы вернуть 1 строку на OID из левой таблицы,где Количество записей в левой таблице равно количеству совпадающих строк в правой таблице.Запись совпадает, когда OID, RID и FLAG установлены в FLAGS для строки.
Объекты, которые мы сравниваем, имеют следующую структуру:
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 равно FALSE
У меня есть общий запрос, в котором я получу строки, в которых количество OID в cs = количество совпадающих OID в rs.Мне нужен измененный запрос сейчас, где применяются остальные правила.Где мы проверяем, находится ли флаг во флаге для конкретного совпадения строк.
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 };
Как я могу расширить это, чтобы применить дополнительные условия фильтра?То, с чем я борюсь, - это наличие столбцов, где они мне нужны, чтобы создать правильные условия фильтрации.Например, мне нужно сравнить флаги и флаг.Но как мне получить доступ к Флагу и Флагу, чтобы выполнить дополнительный фильтр?
Расширить.Я работаю в основном с 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.
Если бы я прокомментировал последнее добавление к дорогам и раскомментировал следующую строку, изменив флажок на 16, результат был бы: NULL Пожалуйста, прокомментируйте, если вам нужна дополнительная информация.