簡體   English   中英

LINQ檢查列表對象的每個屬性以查看其值是否等於字符串

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM