我想从网络服务中选择所有类别。 web服务没有方法,所以我必须获取所有产品,然后选择这些产品所在的所有类别。当我从webservice接收数据时,我制作WebServiceProduct(ID,Name等)和WebServiceCategory(它的ID,名称等对象。
这不起作用:
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()在anonymus类型上比在我的WebServiceCategory对象和SelectListItem上工作得更好?
答案 0 :(得分:2)
匿名类型具有值相等性。引用类型具有引用相等性。 LINQ to Entities遵循类型的默认语义。但是覆盖Equals
或实现IEquatable
将不起作用,因为LINQ to Entities查询被转换为SQL,而LINQ to Entities无法将任意C#代码转换为SQL。请注意,例如Distinct
的重载采用了比较器aren't supported in 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
};
答案 1 :(得分:0)
您是否尝试在IEquatable<T>
上实施SelectListItem
?
答案 2 :(得分:0)
我认为,它是一个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
});