2012-11-27 360 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