如何获得一个不同的列表来使用EF 4.x DBSet Context和IEqualityComparer?

时间:2012-05-17 20:58:55

标签: asp.net-mvc-3 entity-framework iequalitycomparer

我已经花了好几个小时才得到一个独特的代码来工作。

我正在使用EF 4.3,MVC3,Razor并尝试获取列表downto产品ID和名称。 当我对DB运行Sql查询时,没关系。

Sql Query是

SELECT DISTINCT [ProductId]
      ,[Product_Name]
  FROM [dbo].[PRODUCT]

该表中唯一的另一列是国家/地区代码,这就是标准distinct()不起作用的原因。

我已经创建了IEqualityComparer

这是代码:

public class DistinctProduct : IEqualityComparer<PRODUCT>
    {
        public bool Equals(PRODUCT x, PRODUCT y)
        {
            return x.ProductId.Equals(y.ProductId);
        }

        public int GetHashCode(PRODUCT obj)
        {
            return obj.ProductId.GetHashCode();
        }
    }

这是我打电话的地方。

IEqualityComparer<PRODUCT> customComparer = new DistinctProduct();
IEnumerable<PRODUCT> y = db.PRODUCTs.Distinct(customComparer);

但当它击中最后一行时,我发现了一个错误,说明......

LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[MyService.Models.PRODUCT] Distinct[PRODUCT](System.Linq.IQueryable`1[MyService.Models.PRODUCT], System.Collections.Generic.IEqualityComparer`1[MyService.Models.PRODUCT])' method, and this method cannot be translated into a store expression.

谁能告诉我我做错了什么?

谢谢,

大卫

2 个答案:

答案 0 :(得分:3)

你有什么理由不能使用与以下类似的区别吗?

var distinctProdcts = (from p in db.PRODUCTs
                       select new { 
                           ProductId = p.ProductId, 
                           Product_Name = p.ProductName 
                      }).Distinct();

这将在您执行distinct之前从查询中删除国家/地区代码。

答案 1 :(得分:2)

实体框架正在尝试将您的查询转换为SQL查询。显然它不知道如何翻译IEqualityComparerer。我认为问题在于您是否要在数据库中执行Distinct(在这种情况下,您的客户端只获取过滤结果),或者您可以将所有数据带到客户端并在客户端上选择distinct。如果您希望在数据库端进行过滤(这将使您的应用程序执行得更好),并且您希望能够使用不同的策略进行比较,则可以提出在查询之上构建不同条件的代码。如果您可以将数据带到客户端(请注意它可以很多数据),您应该可以这样做(.ToList()将触发查询数据库并实现结果) :

IEnumerable<PRODUCT> y = db.PRODUCTs.ToList().Distinct(customComparer);