【问题标题】:Linq to SQL order by with DistinctLinq to SQL order by with Distinct
【发布时间】:2014-09-26 21:03:47
【问题描述】:

我的环境:VS 2013 Express 中的 ASP.net 和 C#。

我已经阅读了许多类似的 SO 文章,试图解决这个问题。一般来说,我是 Linq to SQL 查询和 c# 的业余爱好者。

我正在尝试使用 Linq to SQL 从列中获取前 5 个最近的不同值,然后将它们添加到列表中。我的应用程序是 asp.net,使用 c# 和 .dbml 文件进行数据抽象。

我尝试了很多不同的方法。我要么得到非不同但排序的列表,要么得到一个不同的未排序列表。到目前为止我所拥有的如下

var Top5MFG = (from mfg in db.orders 
           where mfg.manufacturer.Length > 0 && mfg.customerid == "blahblahblahblahblah"<br />
           select new { 
              manufacturer = mfg.manufacturer,
              date = mfg.date_created 
                       })
        .Distinct()
        .OrderByDescending(s => s.date);

我认为我的“Distinct”正在查看“ID”列,也许我需要告诉它我希望它查看“制造商”列,但我还没有弄清楚如何/如果它是可以这样做。

我可以通过使用存储过程轻松地做到这一点,但如果可能的话,我真的试图直接使用 c# 代码来做到这一点。这是我在 SO 上的第一篇文章,我希望我已经把它正确地放在一起。非常感谢任何帮助。

谢谢

【问题讨论】:

标签: c# linq linq-to-sql


【解决方案1】:

没有Distinct 比较manufacturerdate 对。如果你想通过manufacturer 获得不同的记录,那么我推荐DistinctBy 方法。它在MoreLINQ 库中。因为它是第三个库在 linq to sql 中不支持该方法,您仍然可以通过从 DB 中获取记录并在内存中完成其余操作来使用它

(from mfg in db.orders 
where mfg.manufacturer.Length > 0 && mfg.customerid == "blahblahblahblahblah"
select new { 
             manufacturer = mfg.manufacturer,
             date = mfg.date_created 
           })
 .AsEnumerable()
 .DistinctBy(x => x.manufacturer)
 .OrderByDescending(s => s.date)
 .Take(5);

【讨论】:

  • 谢谢。我收到“Systems.Collections....不包含'DistinctBy'的定义...”Intellisense 也没有提供它作为选项。
【解决方案2】:

我认为你可以使用 GroupBy 来做你想做的事。

  var Top5MFG = db.orders
     .Where (x => x.manufacturer.Length > 0 && x.customerid == "blahblahblahblahblah")
     .GroupBy(mfg => mfg.manufacturer)
     .Select(g => g.First())
     .OrderByDescending(d => d.date_created );
     .Take(5);

【讨论】:

  • 谢谢。这让我非常接近,除了,我只得到一个结果,而我想要 5 个结果。可能是因为 (g => g.First()) 吗?
  • @Silmar 尝试使用FirstOrDefault () 而不是First()
  • 或者只是 .Select(g) 看看会发生什么,否则您可能需要检查您的数据源以验证它是否实际包含 5 个制造商的数据。
  • 恐怕结果相同。我注意到,如果我在 LinqPad 中针对我的数据库运行您的原始建议,它会非常有效。我想知道我的环境是否与它有关。更新了我最初的问题,指出我在 VS 2013 Express 中使用 ASP.net 和 C#。
  • 只尝试过 (g),我得到:“错误 CS0103:名称 'g' 在当前上下文中不存在”
【解决方案3】:

您可以通过某个字段区分的一种方法是替换:

...
.Distinct()
...

与:

...
.GroupBy(x => x.manufacturer )
.Select(g => g.First())
...

【讨论】:

  • 由于 linq 对 ef 的限制,内部 First 查询可能会抛出异常。我记得我尝试过这样的事情,但我得到了 UnsupportedException
  • @Selman22 问题是关于 linq to sql 的,所以这可以正常工作。但是如果是 EF,是的,您需要使用 FirstOrDefault 而不是 First,这是一个非常简单的解决方法。
  • 在 EF Core 中,即使您将其更改为 FirstOrDefault,它也会引发异常。 (Linq 表达式 [...] 无法翻译...)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-31
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多