Ответ 1
Используйте Any()
вместо Содержит:
buildingStatus.Any(item => item.GetCharValue() == v.Status)
У меня есть список, который содержит перечисления. Он является стандартным Enum, но имеет прикрепленный к нему атрибут и метод расширения, который возвращает 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 находится в buildStatus... но помните, что buildStatus - это ILIST перечислений, поэтому я ДОЛЖЕН вызвать GetCharValue.
У меня была некоторая помощь, прежде чем я подумал, что правильный синтаксис
buildingStatus.Contains (v.Status)
но проблема в том, что buildingStatus - это список из списков Enum, поэтому я должен вызвать GetCharValue() для каждого элемента в списке Ilist, прежде чем говорить "Содержит".
Я думал, что есть что-то особенное, чтобы сделать это с помощью лямбда, используя Содержит - так, конечно, это не работает.
where buildingStatus.Contains(item => item.GetCharValue() == v.Status)
Может ли кто-нибудь помочь?
Используйте Any()
вместо Содержит:
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
Эта программа сравнивает строковое представление перечисления и производит тот же вывод:
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 ();
}
Я создал этот метод расширения для преобразования одного IEnumerable в другой, но я не уверен, насколько он эффективен; он может просто создать список за кулисами.
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)
и пропустите создание List<string>
с ConvertAll ()
в начале.
Если я правильно понял, вам нужно преобразовать тип (char), который вы храните в списке Строить список (перечисление), который вы храните в списке buildingStatus.
(Для каждого статуса в списке "Строй" //// значение//, статус имеет место в списке 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;
}