![](/img/trans.png)
[英]Check a list of DTOs using linq to see if all values that exclude a particular value all equal the same thing
[英]LINQ to check each property of a list object to see if it's value is equal to a string
我有一個列表對象,其中包含位置作為對象中的屬性。 我想檢查這些屬性中的任何一個是否等於字符串(即“啟動器”)。 我如何通過LINQ做到這一點而不必單獨檢查每個位置?
例如,如果我有18個位置作為列表項的屬性,並且QB,RB和WR的值為“啟動器”,則我希望這些位置在LINQ查詢中返回。
例:
Public class teamNeeds {
public string QB {get; set;}
public string RB {get; set;}
public string WR {get; set;}
public string TE {get; set;}
.......etc, etc
}
List<teamNeeds> needs = new List<teamNeeds>();
我從該團隊的數據表中獲取信息,每個職位可能有各種各樣的事情-啟動器,備用,深度等等。
在這種情況下,我想查找列表中所有以“ Starter”作為其值的位置(即,循環遍歷列表項的屬性以找到所有值等於“ Starter”的屬性)
所以你需要這個嗎?
string s = "Starter";
var result = needs
.Where(t => t.QB == s || t.RB == s || t.WR == s || t.TE == s...)
.ToList();
唯一的問題是,您不想編寫18個條件? 您可以動態構建表達式:
Type type = typeof(teamNeeds);
Expression cond = Expression.Constant(false);
ParameterExpression par = Expression.Parameter(type);
ConstantExpression ces = Expression.Constant("Starter");
foreach (PropertyInfo property in type.GetProperties())
{
if (property.PropertyType == typeof(string))
{
Expression prop = Expression.Property(par, property.GetMethod);
Expression eq = Expression.Equal(prop, ces);
cond = Expression.OrElse(cond, eq);
}
}
Func<teamNeeds, bool> condFunc = Expression.Lambda<Func<teamNeeds, bool>>(cond, par).Compile();
var result = needs.Where(condFunc).ToList();
不錯的是,如果您需要在服務器查詢上運行條件,則只需更改一行:
Expression<Func<teamNeeds, bool>> condFunc = Expression.Lambda<Func<teamNeeds, bool>>(cond, par);
現在您可以在IQueryable中使用它。
這是使用反射的方法:
class Program
{
static void Main(string[] args)
{
List<TeamNeeds> needs = new List<TeamNeeds>();
TeamNeeds n1 = new TeamNeeds();
n1.QB = "starter";
TeamNeeds n2 = new TeamNeeds();
n2.RB = "starter";
needs.Add(n1);
needs.Add(n2);
foreach (var need in needs)
{
IEnumerable<PropertyInfo> list = need.GetType().GetProperties().Where(prop => (string)prop.GetValue(need, null) == "starter");
foreach (var item in list)
{
//This will give you the propertyName
Console.WriteLine(item.Name);
}
}
Console.ReadLine();
}
}
public class TeamNeeds
{
public string QB { get; set; }
public string RB { get; set; }
public string WR { get; set; }
public string TE { get; set; }
}
但是,這種設計對您來說會更好嗎:
class Program
{
static void BetterMain(string[] args)
{
List<TeamV2> teamList = new List<TeamV2>();
foreach(var team in teamList)
{
List<Player> starters = team.playerList.Where(p => p.isStarter == true).ToList();
starters.ForEach(p => Console.WriteLine(p.positionName));
}
}
}
public class TeamNeeds
{
public string QB { get; set; }
public string RB { get; set; }
public string WR { get; set; }
public string TE { get; set; }
}
public class TeamV2
{
public List<Player> playerList = new List<Player>();
}
public class Player
{
public bool isStarter;
public bool positionName;
}
盡管可以使用LinQ做到這一點,但這並不是最優雅,最有效的方法。 我認為使用簡單的foreach更合適。
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<teamNeeds> list = new List<teamNeeds> {
new teamNeeds("abc", "starter", "ka", "starter")
};
//iterate over list and reflect properties
foreach (var item in list) {
foreach (var prop in item.GetType().GetProperties())
{
if(prop != null && prop.GetValue(item, null).ToString() == "starter")
Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(item, null));
}
}
//same via linq
var selectedViaLinq = list.Select(item =>
{
return item.GetType().GetProperties().Where(prop => prop.GetValue(item, null) == "starter").ToList();
}).ToList();
}
}
public class teamNeeds
{
public teamNeeds(string qb, string rb, string wr, string te)
{
QB = qb;
RB = rb;
WR = wr;
TE = te;
}
public string QB { get; set; }
public string RB { get; set; }
public string WR { get; set; }
public string TE { get; set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.