LINQ Получить отличительные значения и заполнить СПИСОК

Я пытаюсь выяснить, могу ли я использовать LINQ, чтобы предоставить мне различные значения некоторых данных, которые у меня есть в DataTable (FirstName, LastName, QTY). Я могу получить различные значения и заполнить свой список, но мне нужно запустить два разных запроса LINQ, чтобы получить его... Я уверен, что есть лучший способ сделать это:)

Любые предложения будут очень признательны (очень новые для LINQ)

Код:

public static List<StudentData> LinqDistinct(DataTable dt)
{
      DataTable linqTable = dt;

       //get the distinct values
        var query =
            (from names in dt.AsEnumerable()
             select new {
                 FirstName = names.Field<string>("FirstName"),
                 LastName = names.Field<string>("LastName")
             }).Distinct();


        //fill my list with the distinct values
        List<StudentData> sList = (from sa in query.AsEnumerable()
                                   select new StudentData
                                              {
                                                  FirstName = sa.FirstName,
                                                  LastName = sa.LastName
                                                  //Qty = names.Field<int>("Qty")

                                                 }).ToList();                                               



        return sList;}

Ответы

Ответ 1

Любая причина не просто делать проекцию после отчетливого, вам может понадобиться AsEnumerable() после Distinct, но это не имеет большого значения.

public static List<StudentData> LinqDistinct(DataTable dt)
{
    DataTable linqTable = dt;
    return
        (from names in dt.AsEnumerable()
         select new {
             FirstName = names.Field<string>("FirstName"),
             LastName = names.Field<string>("LastName")
         }).Distinct().Select(x =>
             new StudentData() { FirstName=x.FirstName, LastName=x.LastName})
             .ToList();
}

Ответ 2

Из вашего вопроса неясно, является ли значение значением в вашем DataTable или количеством числа дубликатов для данного элемента, как в ответе Ecyrb. Однако, если ваш класс StudentData реализует IEquatable<StudentData> или переопределяет метод Equals, это должно работать:

public static List<StudentData> LinqDistinct(DataTable dt)
{
    return dt.AsEnumerable()
             .Select(row => new StudentData
                            {
                                FirstName = row.Field<string>("FirstName"),
                                LastName = row.Field<string>("LastName"),
                                Qty = row.Field<int>("Qty")
                            })
             .Distinct()
             .ToList();
}

Если StudentData не поддерживает сравнение значений, и вы не можете добавить эту поддержку к классу, возможно, вам придется создать реализацию IEqualityComparer<StudentData> и передать это в метод Distinct.

Ответ 3

Довольно уверен, что вы могли бы просто сделать это...

List<StudentData> sList = (from names in dt.AsEnumerable().Distinct() // I am not sure if you even have to call AsEnumerable()
                 select new StudentData() {
                     FirstName = names.Field<string>("FirstName"),
                     LastName = names.Field<string>("LastName")
                 }).ToList();

Ответ 4

Вы можете использовать GroupBy:

public static List<StudentData> LinqDistinct(DataTable dt)
{
    List<StudentData> results = dt.AsEnumerable()
        .GroupBy(row => 
        {
            FirstName = row.Field<string>("FirstName"),
            LastName = row.Field<string>("LastName")
        })
        .Select(group => new StudentData
        {
            FirstName = group.Key.FirstName,
            LastName = group.Key.LastName,
            Qty = group.Count()
        })
        .ToList();

    return results;
}

class StudentData
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Qty { get; set; }
}