LINQ按名称选择属性 [英] LINQ select property by name

查看:83
本文介绍了LINQ按名称选择属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在LINQ select语句中使用变量.

I'm attempting to use a variable inside of a LINQ select statement.

这是我现在正在做的一个例子.

Here is an example of what I'm doing now.

using System;
using System.Collections.Generic;
using System.Linq;
using Faker;

namespace ConsoleTesting
{
internal class Program
{
    private static void Main(string[] args)
    {
        List<Person> listOfPersons = new List<Person>
        {
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person(),
            new Person()
        };

        var firstNames = Person.GetListOfAFirstNames(listOfPersons);

        foreach (var item in listOfPersons)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine();
        Console.ReadKey();
    }


    public class Person
    {
        public string City { get; set; }
        public string CountryName { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public Person()
        {
            FirstName = NameFaker.Name();
            LastName = NameFaker.LastName();
            City = LocationFaker.City();
            CountryName = LocationFaker.Country();
        }

        public static List<string> GetListOfAFirstNames(IEnumerable<Person> listOfPersons)
        {
            return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
        }

        public static List<string> GetListOfCities(IEnumerable<Person> listOfPersons)
        {
            return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
        }

        public static List<string> GetListOfCountries(IEnumerable<Person> listOfPersons)
        {
            return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
        }

        public static List<string> GetListOfLastNames(IEnumerable<Person> listOfPersons)
        {
            return listOfPersons.Select(x => x.FirstName).Distinct().OrderBy(x => x).ToList();
        }
    }
}
}

我的GetListOf ...方法具有一些不是很干的代码

I have a Some very not DRY code with the GetListOf... Methods

我觉得我应该可以做这样的事情

i feel like i should be able to do something like this

public static List<string> GetListOfProperty(
IEnumerable<Person> listOfPersons, string property)
        {
            return listOfPersons.Select(x =>x.property).Distinct().OrderBy(x=> x).ToList();
        }

但这不是有效的代码.我认为关键可能与创建功能有关

but that is not vaild code. I think the key Might Relate to Creating a Func

如果这就是答案,我该怎么做?

if That is the answer how do I do that?

这是使用反射的第二次尝试,但这也是不行的.

Here is a second attempt using refelection But this is also a no go.

        public static List<string> GetListOfProperty(IEnumerable<Person> 
listOfPersons, string property)
        {
            Person person = new Person();
            Type t = person.GetType();
            PropertyInfo prop = t.GetProperty(property);
            return listOfPersons.Select(prop).Distinct().OrderBy(x => 
x).ToList();
}

我认为这可能是死胡同/红鲱鱼,但我想无论如何我都会展示我的作品.

I think the refection might be a DeadEnd/red herring but i thought i would show my work anyway.

请注意,示例代码实际上已简化,用于通过AJAX填充数据列表创建自动完成的体验.该对象具有20多个属性,我可以通过编写20多个方法来完成,但是我觉得应该有一种DRY方式来完成此操作.同样采用这种方法也将清理我的控制器动作.

Note Sample Code is simplified in reality this is used to populate a datalist via AJAX to Create an autocomplete experience. That object has 20+ properties and I can complete by writing 20+ methods but I feel there should be a DRY way to complete this. Also making this one method also would clean up my controller action a bunch also.

问题:

鉴于代码的第一部分,有一种方法可以将这些相似的方法抽象为一个方法,方法是将一些对象传递到select语句中?

Given the first section of code is there a way to abstract those similar methods into a single method buy passing some object into the select Statement???

谢谢您的时间.

推荐答案

您将必须构建选择

.Select(x =>x.property).

用手

.幸运的是,这并不是一个棘手的问题,因为您希望它始终是同一类型(string),所以:

var x = Expression.Parameter(typeof(Person), "x");
var body = Expression.PropertyOrField(x, property);
var lambda = Expression.Lambda<Func<Person,string>>(body, x);

然后上面的Select变为:

.Select(lambda).

(对于基于IQueryable<T>的LINQ)或

(for LINQ based on IQueryable<T>) or

.Select(lambda.Compile()).

(对于基于IEnumerable<T>的LINQ).

(for LINQ based on IEnumerable<T>).

请注意,您可以执行property来缓存最终表单的任何操作.

Note that anything you can do to cache the final form by property would be good.

这篇关于LINQ按名称选择属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆