Distinct () для класса, типа анонима и SelectListItem - PullRequest
1 голос
/ 02 марта 2010

Я хочу выбрать все категории из веб-сервиса. У веб-службы нет метода для этого, поэтому мне нужно получить все продукты, а затем выбрать все категории, в которых находятся эти продукты. Когда я получаю данные из веб-службы, я создаю WebServiceProduct (ID, Name и т. Д.) И WebServiceCategory Его имя, имя и т. Д.).

Это не работает:

        IQueryable<SelectListItem> categories = (from p in webserviceProductRepository.GetProducts()
                                                 from c in p.Categories
                                                 select new SelectListItem
                                                 {
                                                     Value = c.ID.ToString(),
                                                     Text = c.Name
                                                 }).Distinct().OrderBy(c => c.Text);

Но это работает, когда я впервые выбираю его как тип анонима:

        var foo = (from p in webserviceProductRepository.GetProducts()
                   from c in p.Categories
                   select new
                   {
                       ID = c.ID.ToString(),
                       Name = c.Name
                   }).Distinct().OrderBy(c => c.Name);

        IQueryable<SelectListItem> categories = from c in foo
                                                select new SelectListItem
                                                {
                                                    Value = c.ID.ToString(),
                                                    Text = c.Name
                                                };

Я также пытался с IEqualityComparer и переопределенными Equals и GetHashCode проверить WebServiceCategory.ID, но он также не работает.

Итак, мой вопрос: почему Distinct () лучше работает с анонимным типом, чем с моим объектом WebServiceCategory и SelectListItem?

Ответы [ 3 ]

2 голосов
/ 02 марта 2010

Анонимные типы имеют равенство значений. Ссылочные типы имеют ссылочное равенство. LINQ to Entities следует семантике по умолчанию для типов. Но переопределение Equals или реализация IEquatable не будут работать, потому что запросы LINQ to Entities переводятся в SQL, а LINQ to Entities не может преобразовать произвольный код C # в SQL. Обратите внимание, что перегрузки, например, Distinct, которые принимают компаратор , не поддерживаются в L2E .

У вас уже есть один обходной путь, во втором примере кода. Другой - группировка по анонимному типу:

var categories = from p in webserviceProductRepository.GetProducts()
                 from c in p.Categories
                 group c by new { Id = c.ID, Name = c.Name } into g
                 order by g.Key.Name
                 select new SelectListItem
                 {
                     Value = g.Key.Id.ToString(),
                     Text = g.Key.Name
                 };
0 голосов
/ 02 марта 2010

Я думаю, это объект IQueryable и IEqualityComparer не будет работать для этого объекта. Может быть, это поможет

IQueryable<SelectListItem> categories = (from p in webserviceProductRepository.GetProducts()
                                         from c in p.Categories.Distinct()
                                         orderby c.Name
                                         select new SelectListItem
                                         {
                                             Value = c.ID.ToString(),
                                             Text = c.Name
                                         });
0 голосов
/ 02 марта 2010

Вы пытались реализовать IEquatable<T> на SelectListItem?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...