我有以下声明:
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;
答案 0 :(得分:2)
你的问题很不清楚,但是let
子句可以让你打破子表达式结果。可能是这个(?):
var itemsFromList = from item in ListItems
let Variable = item.Countries
where Variable != null
select item;
我不确定这实际上会实现什么。
我唯一的另一个想法是你在编译时不知道Variable
是什么,想要注入什么东西?
正如@DarenThomas所说,如果Variable
实际上是Linq语句的外部,整个语句就会失效,因为Variable
在每次迭代时都不会发生变化。
答案 1 :(得分:2)
在我看来,变量只是一个变量,它是在以后定义的。如果你真的希望你的表达可以像这样修改,你最好的选择是使用Reflection。
首先,您需要获取所需属性的PropertyInfo的引用。您可以致电Type.GetProperty(string name)来完成此操作。获得PropertyInfo的引用后,您可以通过调用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;
}
}
然后我们可以将多个呼叫链接在一起。例如,如果您想过滤掉“cities”和“Countries”为空的所有条目,您可以使用以下内容:
var NonNullCitiesOrCountries = ListItems.SelectNonNull("Countries")
.SelectNonNull("cities");
注意: SelectNonNull只返回一个IEnuerable。您仍然需要枚举它以获取查询结果。
答案 2 :(得分:0)
如果我正确理解了您的问题,您希望将硬编码字段Country
替换为动态内容。
在这种情况下,您需要将Variable
(让我们称之为getNotNullField
)声明为ListItem
到object
的函数:
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;