【问题标题】:How to linq select WHERE specific properties are not null? [duplicate]如何 linq 选择 WHERE 特定属性不为空? [复制]
【发布时间】:2020-03-23 20:42:02
【问题描述】:

这实际上只是一个语法/格式问题。

目前我有这个说法,

Where(x =>
    x.AddPower != null || x.BaseCurve != null || x.Power != null || x.Axis != null || 
    x.ColorName != null || x.Cylinder != null || x.Diameter != null)

在我没有 7 个“或”条件的情况下,有没有更好的方法来编写这个?在这些特定属性中至少有一个不为空的地方?我正在迭代的对象有一些我不关心的,所以我只需要检查这些。

【问题讨论】:

  • 这能回答你的问题吗? Check if any property of class is null你可以试试这个方案或者添加一个方法来输入,代表x变量
  • 如果这是 Linq to Sql 那么你所拥有的就是“最好”的方法。
  • @PavelAnikhouski 我不这么认为,因为我只需要确保其中一个不为空,并且只有这些特定属性。对象上有一些我不在乎它们是否为空。
  • 为什么要用总是比较晦涩的东西来代替水晶般清晰的代码?您可以为这些属性添加属性并通过反射找到它们,但请问,为什么?
  • 向类添加一个布尔属性,并将逻辑移到那里。仍然会有 7 次检查,但类本身会隐藏该细节。

标签: c# linq select foreach where-clause


【解决方案1】:

你可以不用 7 个OR 条件来写它,但我不认为它更好。基本上,您可以使用反射将所有属性过滤为您关心的属性(通过过滤属于表示属性名称的字符串值数组的Any),然后查看是否有任何不是null:

var valid = items.Where(item => item.GetType().GetProperties()  // Get all properties
    .Where(p => new[]{"AddPower", "BaseCurve", "Power",
        "Axis", "ColorName", "Cylinder", "Diameter"}
        .Any(propName => propName == p.Name))          // Filter on names we care about
    .Any(p => p.GetValue(item) != null));              // Return true if any are not null

【讨论】:

    【解决方案2】:

    您写道:至少这些特定属性中的一个不为空?

    这意味着您必须在某处指定要检查哪些属性以及您不关心哪些属性。

    下面我假设您正在枚举MyType的序列

    我们先做一个扩展函数,输入一个MyType的对象,输出你要选择的属性。见extension methods demystified

    public static IEnumerable<object> PropertiesToCheck(this MyType myObject)
    {
        return new object[]
        {
             myObject.AddPower,
             myObject.BaseCurve,
             ...
             myObject.Diameter,
        };
    }
    

    现在您可以更改我们的声明:

    var myLingStatement = mySequence
        .Where(x => x.PropertiesToCheck.Any(propertyToCheck) != null);
    

    【讨论】:

      【解决方案3】:

      根据声明的类型,您可以使用 System.Reflections。

      bool notNull = Type.GetFields().All(x => x.GetValue(instance) != null);
      bool notNull Type.GetProperties().All(x => x.GetValue(instance) != null);
      

      我觉得这个方法比使用 7 .Where() 更好,因为类可以随时展开, 当 Model 发生变化时,你不能总是更新这个 Validator 类。 我认为这会对你有所帮助:d

      【讨论】:

      • lambda 中的x 不是字段/属性的值,而是FieldInfo/PropertyInfo,它不会为空。将x != null 替换为x.GetValue(item) != null
      • 此代码检查 All 属性是否不为空,而 OP 想要检查 AnyAny 特定属性是否不为空...
      猜你喜欢
      • 1970-01-01
      • 2016-06-15
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多