Search code examples
c#linqanonymous-types

Linq Join multi key one side of key is null


Trying to join two tables where part of the key on one side is nullable. Getting "Type arguments cannot be inferred from the usage", which I believe is related to the mismatched types in the key.

TableA.GroupJoin(TableB,
  a => new {a.IntKeyA, a.StringKeyA},
  b => new {b.NullIntKeyB, b.StringKeyB}
 (tabA, tabB) => new {tabA, tabB});

Tried to cast the type of the key in TableA

a => new (int?, string) {a.IntKeyA, a.StringKeyA}

or

a => (int?, string)(new  {a.IntKeyA, a.StringKeyA})

Tried to Coalesce the key in TableB, magic number 0 isn't great but would have worked in this scenario.

b => new {b.NullIntKeyB ?? 0, b.StringKeyB} 

Tried GetValueOrDefault

b => new {b.NullIntKeyB.GetValueOrDefault(), b.StringKeyB}

I suppose I could probably define a class to hold the key but I don't really want to do that every time this issue comes up.


Solution

  • For the time being, this seems to have worked, but I'm not going to mark it as the answer yet in hopes there's an easier way.

    class ReportKey
    {
        private int? IntKey { get; }
        private string StringKey { get; } = string.Empty;
       
        internal ReportKey(int? intKey, string stringKey)
        {
            IntKey = intKey;
            StringKey = stringKey;
        }
        
        public override bool Equals(object obj)
        {
            var item = obj as ReportKey;
        
            if (item == null) return false;
        
            return this.IntKey == item.Intkey &&
               StringKey == item.StringKey;
        }
        
        public override int GetHashCode()
        {
            return $"{IntKey}{StringKey}".GetHashCode();
        }
    }
    

    ...

    TableA.GroupJoin(TableB,
        a => new ReportKey(a.IntKeyA, a.StringKeyA),
        b => new ReportKey(b.NullIntKeyB, b.StringKeyB),
       (tabA, tabB) => new {tabA, tabB});