Подтвердить что ты не робот

Получить отдельные записи, используя linq для сущности

Привет, я использую linq для объекта в своем приложении. Мне нужно получить разные записи на основе одного значения столбца "Имя"

Итак, у меня есть таблица, похожая на приведенную ниже:

(User)
ID
Name
Country
DateCreated

Мне нужно выбрать все эти элементы, но уникально на основе имени (уникально). Можно ли использовать linq, если да, пожалуйста, покажите мне, как это сделать.

var items = (from i in user select new  {i.id, i.name, i.country, i.datecreated}).Distinct();
4b9b3361

Ответ 1

Метод Distinct() работает не так, потому что он не отправляет предикат DISTINCT SQL в базу данных. Вместо этого используйте group:

var distinctResult = from c in result
             group c by c.Id into uniqueIds
             select uniqueIds.FirstOrDefault();

Группа LINQ фактически создает подгруппы объектов, на которые указывает указанное свойство:

Smith
  John
  Mary
  Ed
Jones
  Jerry
  Bob
  Sally

Синтаксис выше возвращает ключи, в результате чего создается отдельный список. Дополнительная информация здесь:

http://imar.spaanjaars.com/546/using-grouping-instead-of-distinct-in-entity-framework-to-optimize-performance

Ответ 2

Простым способом LINQ является группировка по имени, выбор отдельных групп по ключу, затем выбор на основе этого.

from i in user
group new {i.ID, i.Country, i.DateRecord} by i.Name into byNmGp
select byNmGp.First();

Edit: Entity Framework, конечно, очень популярный поставщик linq, но здесь он не обрабатывает First(), хотя логически эквивалентный (в данном случае) FirstOrDefault() будет работать нормально. Я предпочитаю First(), когда его не принуждают к FirstOrDefault() ограничениями EF, потому что его значение лучше соответствует тому, что здесь предлагается.

Другой способ - определить вспомогательный класс:

private class MyRecord : IEquatable<MyRecord>
{
  public int ID;
  public string Name;
  public string Country;
  public DateTime DateCreated;
  public bool Equals(MyRecord other)
  {
    return Name.Equals(other.Name);
  }
  public override bool Equals(object obj)
  {
    return obj is MyRecord && Equals((MyRecord)obj);
  }
  public override int GetHashCode()
  {
    return Name.GetHashCode();
  }
}
/*...*/
var items = (from i in user select new MyRecord {i.ID, i.Name, i.Country, i.DateRecord}).Distinct();

Это просто определяет разные по-разному. Производительность будет отличаться от того, может ли поставщик запроса интерпретировать это определение равенства или нет. Удобство будет отличаться в зависимости от того, имеете ли вы аналогичные запросы LINQ, делая то же самое или нет.

Ответ 3

Вы можете использовать что-то вроде этого:

var distinctReports = reports.Select(c => c.CompanyCode)
                             .Distinct()
                             .Select(c => reports.FirstOrDefault(r => r.CompanyCode == c))
                             .ToList();

Ответ 4

Привет, вот как вы можете выбрать отдельные записи с внутренним соединением. Надеюсь, что это поможет.

var distinctrecords = 
(entity.Table.Join(entity.Table2, x => x.Column, y => y.Column, (x, y) => new {x, y})
             .Select(@t => new {@t.x.Column2, @t.y.Column3}))
             .GroupBy(t => t.Column2)
             .Select(g => g.FirstOrDefault());

Ответ 5

Вот еще один вариант, который я использовал, основываясь на ответе Светланы. Показывает пример заполнения элемента управления GridView уникальными значениями. Спасибо!

        dataGridView_AnalyzeTestSuites.DataSource = (
            from tr in _db.TestResults
            where tr.TaskId == taskId
            select new { TestSuiteName = tr.Test.TestSuite.Name }
            ).Distinct().ToList();