2012-11-27 254 views
3

我不确定我错过了什么,但我一直在整个下午都在这个活动中摔跤。Linq to Entities Select Distinct

我公司的SQL Server视图,看起来像这样:

CompanyId varchar(30) NOT NULL 
CompanyName varchar(100) NOT NULL 
CompanyPriority int NULL 
ConfigItem int NOT NULL 

随着数据,看起来有点像这样:

00001 | Company One | 99 | 123 
00001 | Company One | 99 | 456 
00001 | Company One | 99 | 789 
00002 | Company Two | 99 | 123 
00002 | Company Two | 99 | 456 

我试图得到一个不同的列表公司。 SQL查询我想exectute是

select distinct CompanyId, CompanyName,CompanyPriority from vwCompany 

这给了我正是我想这将是

00001 | Company One | 99 
00002 | Company Two | 99 

结果但对我的生活,我不能找到LINQ查询导致这个SQL,或任何产生相同结果的东西。

我发现的所有问题都使用分组,在我的单元测试中工作正常,但在针对实际数据库执行时未能返回不同的结果。

编辑:

所以我尝试了一些基于迄今为止的答案。

Dim data = _miRepository.GetCompanies(). 
    Select(Function(c) New With { 
      .companyId = c.CompanyId, 
      .companyName = c.CompanyName, 
      .companyPriority = c.CompanyPriority 
     } 
     ).Distinct().ToList() 

生成SQL

SELECT 
1 AS [C1], 
[Extent1].[CompanyId] AS [CompanyId], 
[Extent1].[CompanyName] AS [CompanyName], 
[Extent1].[CompanyPriority] AS [CompanyPriority] 
FROM (SELECT 
     [vwCompany].[CompanyId] AS [CompanyId], 
     [vwCompany].[CompanyName] AS [CompanyName], 
     [vwCompany].[CompanyPriority] AS [CompanyPriority], 
     [vwCompany].[CiId] AS [CiId] 
     FROM [dbo].[vwCompany] AS [vwCompany]) AS [Extent1] 

不具备的独特运营商它在所有:(

是的,我在VB.NET这样做只是为了让它很难找到很好的例子:\

编辑2:

我试图得到尽可能接近埃里克的js ANSW呃,我可以在VB中。

Dim data = (From c In _miRepository.GetCompanies() 
      Select New With {.companyId = c.CompanyId, 
          .companyName = c.CompanyName, 
          .companyPriority = c.CompanyPriority 
          } 
         ).Distinct().ToList() 

给我

SELECT 
1 AS [C1], 
[Extent1].[CompanyId] AS [CompanyId], 
[Extent1].[CompanyName] AS [CompanyName], 
[Extent1].[CompanyPriority] AS [CompanyPriority] 
FROM (SELECT 
     [vwCompany].[CompanyId] AS [CompanyId], 
     [vwCompany].[CompanyName] AS [CompanyName], 
     [vwCompany].[CompanyPriority] AS [CompanyPriority], 
     [vwCompany].[CiId] AS [CiId] 
     FROM [dbo].[vwCompany] AS [vwCompany]) AS [Extent1] 

仍然没有明显的关键字来找到:(

也许有在VB.NET一个微妙的差异,我很想念。

编辑3 :

为了继续这个应用程序的其余部分我已经放弃了莫并在问题开始时使用sql语句创建了一个新视图(vwDistinctCompanies)。

如果有人设法让VB.NET在Sql视图下工作,请告诉我。相当为什么这应该是如此困难的LINQ我不知道:(

+0

万一你还在尝试,我自己尝试了多个查询,并尝试了其他用户的不同查询。看起来@Eric J.给出的答案是使用'DISTINCT'关键字的SQL语句。我不知道如何将它翻译为VB,因为我通过C运行它们# – Steven

+0

感谢您的尝试。我无法让他们中的任何人做出明确的查询。我不确定是因为它在VB中,还是因为它不符合视图而不是表格。 – Nick

+0

嘿,我跑了更多的疑问。看看我编辑的答案。希望能帮助到你。 – Steven

回答

2

尝试使用.Distinct()在您的查询,例如,

(from r in ctx.MyTable where SomeCondition select r).Distinct(); 

http://msdn.microsoft.com/en-us/library/system.linq.enumerable.distinct.aspx

如果需要,还可以提供的IEqualityComparer。但是,要使用IEqualityComparer,必须首先使用结果化的枚举。 ToEnumerable()。这样做意味着Distinct()操作在客户端而不是数据库服务器上执行。

http://msdn.microsoft.com/en-us/library/bb338049.aspx

的的IEqualityComparer允许你准确控制其记录视为相等,因此不从其他记录不同。

如果你只需要选择你的表列的子集,改变

select r 

以选择一个匿名类型是这样的:

(from r in ctx.MyTable where SomeCondition 
    select new 
    { 
     CompanyId = r.CompanyId, 
     CompanyName = r.CompanyName, 
     CompanyPriority = r.CompanyPriority 
    } 
).Distinct(); 

,或者如果你需要一个强类型的对象(例如,因为您在MVC中使用强类型视图:

public class CompanyModel 
{ 
    public int CompanyId { get; set; } 
    public string CompanyName { get; set; } 
    public int CompanyPriority { get; set; } 
} 

// Then in the Linq statement 

(from r in ctx.MyTable where SomeCondition 
    select new CompanyModel() 
    { 
     CompanyId = r.CompanyId, 
     CompanyName = r.CompanyName, 
     CompanyPriority = r.CompanyPriority 
    } 
).Distinct(); 
0

尝试:

var results = (from company in context.Companies 
    select new { 
     CompanyId = company.CompanyId, 
     CompanyName = company.CompanyName, 
     CompanyPriority = company.CompanyPriority 
    }).Distinct(); 

,关键是要得到查询可以是唯一的共同的碎片,然后调用.Distinct()扩展。如果您将configID属性留在那里,它们都将是唯一的。

0
var query = from c in context.vwCompany 
      group c by new { 
       c.CompanyId, 
       c.CompanyName, 
       c.CompanyPriority } into g 
      select g.Key; 

生成的查询(从SQL Server事件探查器)看起来像:

SELECT 
1 AS [C1], 
[Distinct1].[CompanyId] AS [CompanyId], 
[Distinct1].[CompanyName] AS [CompanyName] 
[Distinct1].[CompanyPriority] AS [CompanyPriority] 
FROM (SELECT DISTINCT 
    [Extent1].[CompanyId] AS [CompanyId], 
    [Extent1].[CompanyName] AS [CompanyName] 
    [Extent1].[CompanyPriority] AS [CompanyPriority] 
    FROM [dbo].[vwCompany] AS [Extent1] 
) AS [Distinct1] 
1

-EDITED: -

忽略我所有的代码,我以后前面提到的(一切结束编辑部分)。我试着进一步测试。插入下面的VB代码,并告诉我什么结果你得到:

(From c In ctx.Companies Select New With { _ 
    Key .companyId = c.CompanyId, _ 
    Key .companyName = c.CompanyName, _ 
    Key .companyPriority = c.CompanyPriority _ 
}).Distinct() 

我测试了他们使用LINQPad,我得到了下面的SQL:

SELECT DISTINCT [t0].[CompanyId] AS [companyId], 
       [t0].[CompanyName] AS [companyName], 
       [t0].[CompanyPriority] AS [companyPriority] 
FROM [Companies] AS [t0] 

-END编辑 -

我前几天有过这个问题。这就是我最终做的。

你在找什么需要GroupBy条款,就像你在文章中提到的那样。只是使用Distinct将不会如你所期望的那样工作(据我所知)。下面的lambda表达式就是我所做的,紧接着是通过lambda代码生成的SQL语句。

LAMBDA代码:

Companies.GroupBy(c => new { 
          c.CompanyId, 
          c.CompanyName, 
          c.CompanyPriority 
         }) 
     .Select(p => new { 
          CompanyId = p.Key.CompanyId, 
          CompanyName = p.Key.CompanyName, 
          CompanyPriority = p.Key.CompanyPriority 
         }) 

SQL代码:

SELECT [t0].[CompanyId] AS [companyId], 
     [t0].[CompanyName] AS [companyName], 
     [t0].[CompanyPriority] AS [companyPriority] 
FROM [Companies] AS [t0] 
GROUP BY [t0].[CompanyId], 
     [t0].[CompanyName], 
     [t0].[CompanyPriority] 
+0

奇怪的是它可以在LinqPad中使用,但不适用于我的应用程序。我想知道这是因为它是否针对ObjectSet上的IQuerable,或者它是否只是该项目针对的EF版本。不幸的是,我已经草拟了一半,以涵盖正在休假的原始开发人员。当我有一点喘息的余地时,我会回到这里(我有2小时直到冲刺检查,我需要现在工作的东西:\)。 – Nick

0

难道不应该是两个表?一个与

00001 | Company One | 99 
00002 | Company Two | 99 

和其他与

00001 | 123 
00001 | 456 
00001 | 789 
00002 | 123 
00002 | 456 

这是更规范化,将使您的查询很容易?

+0

是的,它应该,不幸的是,这个决定超出了我的手:( – Nick