Asp.net mvc 类、匿名类型和SelectListItem上的Distinct()

Asp.net mvc 类、匿名类型和SelectListItem上的Distinct(),asp.net-mvc,linq-to-entities,distinct,Asp.net Mvc,Linq To Entities,Distinct,我想从Web服务中选择所有类别。Web服务没有这样的方法,所以我必须获取所有产品,然后选择这些产品所在的所有类别。当我从webservice接收数据时,我将WebServiceProduct ID、Name等和WebServiceCategory ID、Name等作为它的对象 这不起作用: IQueryable<SelectListItem> categories = (from p in webserviceProductRepository.GetProducts

我想从Web服务中选择所有类别。Web服务没有这样的方法,所以我必须获取所有产品,然后选择这些产品所在的所有类别。当我从webservice接收数据时,我将WebServiceProduct ID、Name等和WebServiceCategory ID、Name等作为它的对象

这不起作用:

        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上工作得更好?

您尝试过在SelectListItem上实现IEquatable吗?

我认为,它是一个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
                                         });

匿名类型的值相等。引用类型具有引用相等性。LINQtoEntities遵循类型的默认语义。但是重写Equals或实现IEquatable是行不通的,因为LINQ-to-Entities查询被转换为SQL,而LINQ-to-Entities无法将任意C代码转换为SQL。请注意,的重载,例如,使用比较器的Distinct

在第二个代码示例中,您已经有了一个变通方法。另一种方法是按匿名类型分组:

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
                 };

我想,如果web服务或存储库没有通过此代码区分值,那么我将稍后尝试。必须在不同的值之后将值存入内存。当你使用匿名类型时,什么是“foo”类型?你能详细说明一下…不起作用吗?它会返回所有WebServiceCategory,而不仅仅是不同的类别。