Home > database >  Linq "where" condition with nullable object property result in "invoke non static met
Linq "where" condition with nullable object property result in "invoke non static met

Time:11-16

I've tried to find a similar question but I haven't found exactly what I want. I have this issue: about the following code I am not able to find a way to manage that if devTab is null then his property ID is not available and the where condition t.IDDevTab ==devTab.ID leads to null reference error. Mind that t.IDDevTab is not nullable in the DB. I have tried to insert some additional conditions to the Where but it resulted in error: invoke non static method requires a target. I would obtain a empty list in "DeviceTabColumnsNameAndDesc" if "devTab" is null!

DeviceTable devTab = (from t in _db.DeviceTables
                      where t.DeviceType == devtype && t.IDPlant == id
                      select t)
                      .FirstOrDefault();

var DeviceTabColumnsNameAndDesc = (from t in _db.DeviceTabCols
                                   where t.IDDevTab == devTab.ID
                                       && t.MeasureFamily != "KEY"
                                       && t.MeasureFamily != "DATETIME"
                                   select new
                                   {
                                       colName = t.ColumnName,
                                       colDescr = t.ColumnDescr
                                   })
                                   .ToList();

Is there a workaround of this problem? Thank you in advance.

CodePudding user response:

So, if devTab is null you want a new empty list of anonymous type.. Awkward, but doable:

DeviceTable devTab = (from t in _db.DeviceTables
                  where t.DeviceType == devtype && t.IDPlant == id
                  select t)
                  .FirstOrDefault();

var DeviceTabColumnsNameAndDesc = devTab == null ?
  Enumerable.Empty<object>().Select(x => new { colName = "", colDescr = "" }).ToList() :
  (
    from t in _db.DeviceTabCols
    where t.IDDevTab == devTab.ID && t.MeasureFamily != "KEY" && t.MeasureFamily != "DATETIME"
    select new {
      colName = t.ColumnName,
      colDescr = t.ColumnDescr
    }
  ).ToList();

If you wanted to switch away from anonymous types in this case, you could look at ValueTuple:

var DeviceTabColumnsNameAndDesc = devTab == null ?
  new List<(string colName, string colDesc)>() :
  (
    from t in _db.DeviceTabCols
    where t.IDDevTab == devTab.ID && t.MeasureFamily != "KEY" && t.MeasureFamily != "DATETIME"
    select (
      colName: t.ColumnName,
      colDescr: t.ColumnDescr
    )
  ).ToList();

Or make a record, which is like a class but with some extra bits that make it useful as a data holder:

//defined in a namespace
public record ColThing(string ColName, string ColDesc);

var DeviceTabColumnsNameAndDesc = devTab == null ?
  new List<ColThing>() :
  (
    from t in _db.DeviceTabCols
    where t.IDDevTab == devTab.ID && t.MeasureFamily != "KEY" && t.MeasureFamily != "DATETIME"
    select new ColThing(t.ColumnName, t.ColumnDescr)
  ).ToList();
  • Related