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();
位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();