LINQ:“包含”和一个Lambda查询

我有一个列表,其中包含枚举,它是一个标准的枚举,但有一个属性附加到一个扩展方法返回枚举的CHAR(见下面的GetCharValue),扩展工程很好。

现在我有(linq的另一个扩展方法)

public static IQueryable<Building> WithStatus(this IQueryable<Building> qry, IList<BuildingStatuses> buildingStatus) { return from v in qry where buildingStatus.Where(item => item.GetCharValue() == v.Status) select v; } 

我基本上需要说“返回”查询中的一切,但只有当v.Status在buildingStatus中…但记住buildingStatus是枚举的ILIST,所以我必须调用GetCharValue。

以前我有一些帮助,我认为正确的语法是

 buildingStatus.Contains (v.Status) 

但问题是在这里,buildingStatus是枚举的枚举,所以我必须调用GetCharValue()在Ilist中的每个项目之前说包含..

我以为有什么特别的方式来做这个lambda使用Contains像这样 – 当然这是行不通的

 where buildingStatus.Contains(item => item.GetCharValue() == v.Status) 

谁能帮忙?

使用Any()而不是Contains:

 buildingStatus.Any(item => item.GetCharValue() == v.Status) 

Linq扩展方法任何可以为你工作…

 buildingStatus.Any(item => item.GetCharValue() == v.Status) 

我不确定你正在寻找什么,但是这个程序:

  public class Building { public enum StatusType { open, closed, weird, }; public string Name { get; set; } public StatusType Status { get; set; } } public static List <Building> buildingList = new List<Building> () { new Building () { Name = "one", Status = Building.StatusType.open }, new Building () { Name = "two", Status = Building.StatusType.closed }, new Building () { Name = "three", Status = Building.StatusType.weird }, new Building () { Name = "four", Status = Building.StatusType.open }, new Building () { Name = "five", Status = Building.StatusType.closed }, new Building () { Name = "six", Status = Building.StatusType.weird }, }; static void Main (string [] args) { var statusList = new List<Building.StatusType> () { Building.StatusType.open, Building.StatusType.closed }; var q = from building in buildingList where statusList.Contains (building.Status) select building; foreach ( var b in q ) Console.WriteLine ("{0}: {1}", b.Name, b.Status); } 

产生预期的输出:

 one: open two: closed four: open five: closed 

该程序比较枚举的string表示并生成相同的输出:

  public class Building { public enum StatusType { open, closed, weird, }; public string Name { get; set; } public string Status { get; set; } } public static List <Building> buildingList = new List<Building> () { new Building () { Name = "one", Status = "open" }, new Building () { Name = "two", Status = "closed" }, new Building () { Name = "three", Status = "weird" }, new Building () { Name = "four", Status = "open" }, new Building () { Name = "five", Status = "closed" }, new Building () { Name = "six", Status = "weird" }, }; static void Main (string [] args) { var statusList = new List<Building.StatusType> () { Building.StatusType.open, Building.StatusType.closed }; var statusStringList = statusList.ConvertAll <string> (st => st.ToString ()); var q = from building in buildingList where statusStringList.Contains (building.Status) select building; foreach ( var b in q ) Console.WriteLine ("{0}: {1}", b.Name, b.Status); Console.ReadKey (); } 

我创build了这个扩展方法来转换一个IEnumerable到另一个,但我不知道它是多么高效; 它可能只是在幕后创build一个列表。

 public static IEnumerable <TResult> ConvertEach (IEnumerable <TSource> sources, Func <TSource,TResult> convert) { foreach ( TSource source in sources ) yield return convert (source); } 

那么你可以把where子句改成:

 where statusList.ConvertEach <string> (status => status.GetCharValue()). Contains (v.Status) 

并在开始处用ConvertAll ()跳过创buildList<string>

如果我理解正确,您需要将您在Building列表中存储的types(char值)转换为您在buildingStatus列表中存储的types(枚举)。

(对于Building列表中的每个状态//字符值//状态是否存在于buildingStatus列表中//枚举值//)

 public static IQueryable<Building> WithStatus(this IQueryable<Building> qry, IList<BuildingStatuses> buildingStatus) { return from v in qry where ContainsStatus(v.Status) select v; } private bool ContainsStatus(v.Status) { foreach(Enum value in Enum.GetValues(typeof(buildingStatus))) { If v.Status == value.GetCharValue(); return true; } return false; }