1

BitTable

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

BitMask Table

DataId DataMask
12 3
13 3
14 6

SQL Query and Output

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

My SQL query is giving me desired out put, I am trying to convert this to C# Linq query, but couldn't find any examples on how to do Join using a bit mask condition.

I am able to query Single table using Linq like below, but not sure how to join the other 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
                       

Any help would be much appreciated!

ssilas777
  • 9,672
  • 4
  • 45
  • 68
  • LINQ join results in 1 table, and on acts like where, where are you stuck joining on a condition? [mre] Whereever you're first stuck, it's going to be an easilly found faq. – philipxy Mar 02 '21 at 02:42
  • I am stuck on how to put an on condition like this (bitmask bm on bm.DataMask & bt.BitId = bt.BitId), what ever i tried is giving compilation error. so kind os stuck – ssilas777 Mar 02 '21 at 02:46
  • 1
    What did you try? It would be best to show that. – ProgrammingLlama Mar 02 '21 at 02:46
  • 1
    [Does this answer your question?](https://stackoverflow.com/a/29310640/3181933) – ProgrammingLlama Mar 02 '21 at 02:48
  • Let me edit, few ways am trying – ssilas777 Mar 02 '21 at 02:51
  • 1
    Please in code questions give a [mre]--cut & paste & runnable code, including smallest representative example input as code; desired & actual output (including verbatim error messages); tags & versions; clear specification & explanation. Give the least code you can give that is code that you show is OK extended by code that you show is not OK. (Debugging fundamental.) For SQL that includes DBMS & DDL (including constraints & indexes) & input as code formatted as a table. [ask] Stop trying to code your overall goal & explain what you expected instead from the given code & why. – philipxy Mar 02 '21 at 02:52
  • 1
    FYI, if your join isn't a straight equals then do a full join and put the condition into the where. – juharr Mar 02 '21 at 03:12

1 Answers1

3

LINQ joins are of the following form:

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

The condition must be of the form f(x) equals g(y). The LHS of equals must be a function of an element in table1, and the RHS must be a function of an element in table2. What you have here instead, is something like f(x, y) equals g(x), which is not in that form, so you can't use the join clause, or the Join method here.

A workaround is the trusty old where clauses:

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

Alternative with 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();
ssilas777
  • 9,672
  • 4
  • 45
  • 68
Sweeper
  • 213,210
  • 22
  • 193
  • 313