【问题标题】:Linq Join using bit mask logicLinq Join 使用位掩码逻辑
【发布时间】:2021-03-02 02:21:44
【问题描述】:

位表

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

位掩码表

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 查询单个表,但不确定如何加入另一个表

   [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 加入结果为 1 个表,并且在诸如在哪里、在哪里加入某个条件? minimal reproducible example 无论你第一次遇到什么问题,它都会很容易找到。
  • 你尝试了什么?最好证明这一点。
  • 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出您可以给出的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 停止尝试编写您的总体目标并从给定的代码中解释您的期望以及原因。
  • 仅供参考,如果您的联接不是直接等于,则进行完全联接并将条件放入 where。

标签: c# linq join bitmask


【解决方案1】:

LINQ 连接的形式如下:

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

条件必须采用f(x) equals g(y) 的形式。 equals 的 LHS 必须是 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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2019-05-07
    • 2017-02-23
    • 1970-01-01
    相关资源
    最近更新 更多