Как выбрать определенные поля из динамического списка с помощью LINQ - PullRequest
0 голосов
/ 20 февраля 2019

Я пытаюсь получить некоторые конкретные поля из динамического объекта с фактически списком любого класса, этот класс содержит различные поля из этих полей. Я хочу выбрать некоторые конкретные поля с помощью LINQ, поля, которые я хочу выбратьтакже проходит мимо пользователя.Ниже приведен код, который я пытался использовать System.Linq.Dynamic.

using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Linq.Dynamic;
using System.Collections;

private void Test_Click(object sender, EventArgs e)
{
            List<RateInfo> lst = new List<RateInfo>();
            lst.Add(new RateInfo() { id_country = "IND", id_state = 1, rate = 2.3f });
            lst.Add(new RateInfo() { id_country = "IND", id_state = 2, rate = 1.1f });
            lst.Add(new RateInfo() { id_country = "IND", id_state = 3, rate = 5.2f });
            lst.Add(new RateInfo() { id_country = "IND", id_state = 4, rate = 6.5f });

        GetDynamicData(lst, new List<string>() { "id_country", "id_state" });
}

    private void GetDynamicData(dynamic list, List<string> fetchFields)
    {

        var data = ((IEnumerable)list).Cast<dynamic>()
                        .Select(r => new { r }).AsQueryable();

        StringBuilder s = new StringBuilder();

        //This is for test only. 
        //It works, the value of "id_state" and "id_state" getting appended 
        foreach (var item in data)
        {
            s.Append(item.r.id_state);
            s.Append(",");
            s.Append(item.r.id_country);
        }
        //-----------------------------------------------------


        //Select the specific field data from dynamic list 
        StringBuilder fields = new StringBuilder();

        fields.Append("new (");

        foreach (var fld in fetchFields)
        {
            fields.Append("r." + fld);
            fields.Append(",");
        }
        fields.Remove(fields.Length - 1, 1);
        fields.Append(")");

        //This does not work throws error 
        //"No property or field 'id_country' exists in type 'Object'"
        IQueryable iq = data.Select(fields.ToString());

        //For test only to check the value of selected fields
        foreach (dynamic item in iq)
        {
            s.Append(item.id_state);
            s.Append(",");
            s.Append(item.id_country);
        }

    }

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

вы можете значительно упростить свой метод GetDynamicData, указав явный тип списка (GetDynamicData(IList<RateInfo> list, ...)) и оставив тип элемента списка универсальным, чтобы повторно использовать метод;помня об этом последнем подходе, вы можете переписать GetDynamicData следующим образом, получив желаемый результат:

    private void GetDynamicData<T>(IEnumerable<T> list, List<string> fetchFields)
        {
            var fields = $"new ({string.Join(",", fetchFields)})";
            var res = list.AsQueryable().Select(fields);

            //For test only to check the value of selected fields
            foreach (dynamic item in res) {
                Console.WriteLine(item.id_state);
                Console.WriteLine(item.id_country);
            }

        }

OUTPUT

1
IND
2
IND
3
IND
4
IND

ОБЪЯСНЕНИЕ Я думаю, что разница в том, что указание явнотип (через T или RateInfo), вы заставляете LINQ знать тип элементов списка;если вы используете dynamic, то IQueryable.ElementType экземпляра IQuqryable имеет значение System.Object, поэтому запрос завершится неудачно с возникшей ошибкой.

0 голосов
/ 20 февраля 2019

Вы должны попробовать использовать генерики :

private void GetDynamicData<T>(IEnumerable<T> list, List<string> fetchFields)
{

    var data = list.AsQueryable();
...