具有可空对象 属性 的 Linq "where" 条件导致 "invoke non static method requires a target"

Linq "where" condition with nullable object property result in "invoke non static method requires a target"

我试图找到一个类似的问题,但我没有找到我想要的。 我有这个问题:关于以下代码,我无法找到一种方法来管理如果 devTab 为 null 那么他的 属性 ID 不可用并且 where条件 t.IDDevTab ==devTab.ID 导致 null reference error。请注意 t.IDDevTab 在数据库中不可为空。我试图向 Where 插入一些额外的条件,但它导致了错误:invoke non static method requires a target。如果“devTab”为空,我将在“DeviceTabColumnsNameAndDesc”中获得一个空列表!

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

这个问题有解决办法吗?提前谢谢你。

因此,如果 devTab 为 null,您需要一个新的匿名类型的空列表。尴尬,但可行:

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

如果您想在这种情况下摆脱匿名类型,您可以查看 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();

或者制作一个记录,它类似于 class 但有一些额外的位使其可用作数据保存者:

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