Linq Join 使用位掩码逻辑

Linq Join using bit mask logic

位Table

Id Name BitId
1 TestData1 1
2 TestData2 2
7 TestData3 4

位掩码Table

DataId DataMask
12 3
13 3
14 6

SQL 查询和输出

Select * from bittable bt
Inner join bitmask bm on bm.DataMask & bt.BitId =  bt.BitId
where  bm.DataMask & 4 = 4
Id Name BitId DataId DataMask
2 TestData2 2 14 6
7 TestData3 4 14 6

我的 SQL 查询给出了我想要的输出,我正在尝试将其转换为 C# Linq 查询,但找不到任何关于如何使用位掩码条件进行连接的示例。

我可以像下面这样使用 Linq 查询单个 table,但不确定如何加入另一个 table

   [Flags]
   public enum MaskKeys
   {
        TestData1 = 1,
        TestData2 = 2,
        TestData3 = 4
   }

   public class BitMask 
   {
     public int DataId{ get; set; }
     public MaskKeys DataMask{ get; set; }
   }
   
   public class BitTable 
   {
     public int  Id{ get; set; }
     public string Name {get;set}
     public MaskKeys BitId { get; set; }
   }

    var dataMaskList = _context.BitMask
    .Where(x =>((int)x.DataMask & 4) == 4)
    .ToList(); //works

    var dataMaskList = _context.BitMask
        .Where(x=>x.DataMask.HasFlag(MaskKeys.TestData3)).ToList(); //also works


    var finalResult = _context.BitMask.Join(
                      _context.BitTable,//not sure how to join
                       

如有任何帮助,我们将不胜感激!

LINQ 连接具有以下形式:

from x in table1
join y in table2 on f(x) equals g(y)
select ...

条件的格式必须是f(x) equals g(y)equals 的左轴必须是 table1 中元素的函数,右轴必须是 table2 中元素的函数。相反,您在这里看到的是 f(x, y) equals g(x) 之类的东西,它不是那种形式,因此您不能在此处使用 join 子句或 Join 方法。

解决方法是使用可信赖的旧 where 子句:

var query = from bt in _context.BitTable
            from bm in _context.BitMask
            where (bm.DataMask & bt.BitId) == bt.BitId
            where (bm.DataMask & 4) = 4
            select new {
                bt.Id, bt.Name, bt.BitId, bm.DataId, bm.DataMask
            };
var dataMaskList = query.ToList();

替代HasFlag

var query = from bt in _context.BitTable
            from bm in _context.BitMask
            where bm.DataMask.HasFlag(bt.BitId) && bm.DataMask.HasFlag(MaskKeys.TestData3)
            select new {
                bt.Id, bt.Name, bt.BitId, bm.DataId, bm.DataMask
            };
var dataMaskList = query.ToList();