带有变量的 LINQ 位置

本文关键字:LINQ 位置 变量 | 更新日期: 2023-09-27 18:37:14

我有以下语句:

var itemsFromList = from item in ListItems 
                    where item.Countries != null 
                    select item;

所以我可以返回国家/地区中存在的所有值(有些是空的)。在同一列表中,我还有其他列,例如城市,我必须将其更改为:

var itemsFromList = from item in ListItems 
                    where item.cities != null 
                    select item;

有没有办法使用相同的语句通过使用一个变量来返回不为空的城市或国家/地区,如下所示:

var itemsFromList = from item in ListItems 
                    where item.variable != null 
                    select item;

带有变量的 LINQ 位置

在我看来

,变量就是这样,一个变量,在以后定义的。 如果你真的想让你的表达式像这样修改,你最好的选择是使用反射。

首先,您需要获取对所需属性的属性信息的引用。 您可以通过调用 Type.GetProperty(字符串名称)来执行此操作。 一旦你有了对 PropertyInformation 的引用,你就可以通过调用 PropertyInfo.GetValue(Object obj, Object[] index) 来获取特定实例的值。

下面是创建 LINQ 查询的示例,该查询将仅获取指定属性不为 null 的项。

// Declare this as a Generic method of Type T so that we can pass in a
// List containing anything and easily get the appropriate Type object
public static IEnumerable<T> SelectNonNull<T>(
    IEnumerable<T> ListItems, string propertyName)
{
    IEnumerable<T> itemsFromList;
    // Get a reference to the PropertyInfo for the property
    // we're doing a null-check on.
    PropertyInfo variable = typeof(T).GetProperty(propertyName);
    if (variable == null)
    {
        // The property does not exist on this item type:
        // just return all items
        itemsFromList = from item in ListItems
                        select item;
    }
    else
    {
        itemsFromList = from item in ListItems
                        // GetValue will check the value of item's
                        // instance of the specified property.
                        where variable.GetValue(item, null) != null
                        select item;
    }
    return itemsFromList;
}

要获得问题的结果,您可以像这样使用此函数:

var NonNullCountries = SelectNonNull(ListItems, "Countries");
var NonNullCities = SelectNonNull(ListItems, "cities");

或者,我们可以将其声明为扩展方法(与其他 Linq 方法一样),如下所示:

public static IEnumerable<T> SelectNonNull<T>(
    this IEnumerable<T> source,
    string propertyName)
{
    PropertyInfo variable = typeof(T).GetProperty(propertyName);
    if (variable == null)
    {
        // Specified property does not exist on this item type:
        //just return all items
        return from item in source
                select item;
    }
    else
    {
        return from item in source
                where variable.GetValue(item, null) != null
                select item;
    }
}

然后,我们可以将多个调用链接在一起。 例如,如果要过滤掉"城市"和"国家/地区"为空的所有条目,则可以使用以下条目:

var NonNullCitiesOrCountries = ListItems.SelectNonNull("Countries")
                                        .SelectNonNull("cities");

注意:SelectNonNull 只返回一个 IEnuerable。 您仍然需要枚举它以获取查询结果。

你的问题非常不清楚,但let子句让你分解子表达式结果。可能是这个(?

var itemsFromList = from item in ListItems 
                    let Variable = item.Countries
                    where Variable != null 
                    select item;

我不确定这实际上会达到什么目的。

我唯一的另一个想法是,你不知道编译时Variable是什么,想要注入一些东西?

正如@DarenThomas所说,如果Variable实际上是 Linq 语句的外部,则整个语句将失效,因为Variable不会在每次迭代时发生更改。

如果我

正确理解了您的问题,您希望将硬编码字段Country替换为动态内容。

在这种情况下,您需要将Variable(我们改为getNotNullField)声明为从ListItemobject的函数:

Func<ListItem, object> getNotNullField;
if (...) {
    getNotNullField = item => item.Countries;
} else {
    getNotNullField = item => item.SomeOtherField;
}
...
var itemsFromList = from item in ListItems where getNotNullField(item) != null 
                    select item;