具有可为空对象属性的 Linq“where”条件导致“调用非静态方法需要一个目标”

Posted

技术标签:

【中文标题】具有可为空对象属性的 Linq“where”条件导致“调用非静态方法需要一个目标”【英文标题】:Linq "where" condition with nullable object property result in "invoke non static method requires a target" 【发布时间】:2021-12-26 17:38:50 【问题描述】:

我试图找到一个类似的问题,但我没有找到我想要的。 我有这个问题:关于以下代码,我无法找到一种方法来管理如果devTab 为空,那么他的属性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 为空,您实际上想做什么?如果没有devTab 那么where t.IDDevTab ==devTab.ID 没有意义,那么应该怎么做呢?还是我们根本不应该尝试查找第二个查询? 好点,该列表与另一个列表完全结合使用,如果“devTab”为空,它应该期望 DeviceTabColumnsNameAndDesc 是一个空列表!也许整个代码设计得并不完美我承认! 【参考方案1】:

因此,如果 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();

或者创建一个记录,它就像一个类,但有一些额外的位使其可用作数据持有者:

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

【讨论】:

谢谢,它有效。尴尬请求的事实是由于编辑代码,获得原始解决方案未涵盖它的扩展版本的可能性较小。在实践中维护匿名类型避免了我定义很多结构。 AT 非常适合临时数据需求,但对于更复杂的内容,您可以查看 ValueTuplerecord 之类的内容。我会在答案中添加一点

以上是关于具有可为空对象属性的 Linq“where”条件导致“调用非静态方法需要一个目标”的主要内容,如果未能解决你的问题,请参考以下文章

EF6 - 使用可为空属性(外键,TPH)时的无效 SQL 查询

在 np.where 条件下使用 pandas 可为空的整数 dtype

可为空的对象必须具有一个值

可为空的对象必须具有一个值 是啥原因啊 求解 谢谢

总和可为空的 Linq 查询

在 C# linq 中结合多个具有可选参数的 where 条件?