3

我不确定我错过了什么,但我整个下午都在纠结这个。

我有一个公司的 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 查询是

select distinct CompanyId, CompanyName,CompanyPriority from vwCompany

这给了我我想要的结果

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

但是对于我的一生,我找不到导致这个 sql 的 LINQ 查询,或者任何产生相同结果的东西。

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

编辑:

因此,到目前为止,我已经根据答案尝试了一些事情。

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]

它根本没有 distinct 运算符:(

是的,我在 VB.NET 中这样做只是为了更难找到好的示例:\

编辑2:

我试图在 VB 中尽可能接近 Eric Js 的答案。

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 中会如此困难,我不知道 :(

4

5 回答 5

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();
于 2012-11-27T15:07:22.440 回答
1

-编辑:-

忽略我之前提到的所有代码(结束编辑部分之后的所有内容)。我尝试了进一步的测试。插入下面的 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]

-结束编辑-

几天前我遇到了这个问题。这就是我最终做的。

您正在寻找的内容需要GroupBy您在帖子中提到的条款。仅使用Distinct不会像您期望的那样工作(据我所知)。下面的 lambda 表达式是我所做的,紧随其后的是通过 lambda 代码生成的 SQL 语句。

拉姆达代码:

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]
于 2012-11-27T15:37:52.877 回答
0

尝试:

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

关键是获取可以唯一的查询片段,然后调用.Distinct()扩展。如果您将 configID 属性保留在其中,它们都将是唯一的。

于 2012-11-27T15:09:17.057 回答
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 Profiler)将如下所示:

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]
于 2012-11-27T15:09:35.553 回答
0

不应该是两张桌子吗?一个与

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

而另一个与

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

哪个更规范化并且会使您的查询变得非常容易?

于 2012-11-27T20:14:02.570 回答