首页 > 解决方案 > Linq Join 使用位掩码逻辑

问题描述

位表

ID 姓名 位号
1 测试数据1 1
2 测试数据2 2
7 测试数据3 4

位掩码表

数据标识 数据掩码
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 姓名 位号 数据标识 数据掩码
2 测试数据2 2 14 6
7 测试数据3 4 14 6

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

我可以使用下面的 Linq 查询单个表,但不确定如何加入另一个表

   [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
                       

任何帮助将非常感激!

标签: c#linqjoinbitmask

解决方案


LINQ 联接具有以下形式:

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

条件必须是形式f(x) equals g(y)。的 LHSequals必须是 中的元素的函数table1,而 RHS 必须是 中的元素的函数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();

推荐阅读