【问题标题】:Linq order by ascending sort by descendingLinq 按升序排序
【发布时间】:2015-11-01 04:00:50
【问题描述】:

对不起标题,但我不知道如何写得更好。我会在帖子中尝试。

当我尝试使用带有 orderby 的 linq 从数据库中获取值时,会发生一些奇怪的事情。让我们看看 4 个查询:

//1
var badAsc = new ConcurrentBag<int>((from x in se.produkts orderby x.numerProduktu select x.numerProduktu));
//2                        
var bagDesc = new ConcurrentBag<int>((from x in se.produkts orderby x.numerProduktu descending select x.numerProduktu));
//3
var listAsc = (from x in se.produkts orderby x.numerProduktu select x.numerProduktu).ToList();
//4
var listdesc = (from x in se.produkts orderby x.numerProduktu descending select x.numerProduktu).ToList();

我们有 2 个ConcurrentBags&lt;int&gt; 和 2 个List&lt;int&gt;。我对此的期望是 1 和 3 将相同,2 和 4 也将相同。检查我得到了什么值:

ConcurrentBag&lt;int&gt; 的升序排序实际上是降序。在 Microsoft 网站上,我们可以读到,ConcurrentBag 在排序无关紧要时很好,但正如我们在 bagDesc 中看到的那样,保留了排序。为了表明我在数据库中没有任何奇怪的东西,我还创建了两个List&lt;int&gt;,其中排序保持应有的状态。

在我的数据库中执行 select * from produkt 会得到排序为 listAscbagDesc 的值。

数据库是mssql 2014numerProduktu是这个表的主键。

有人知道那里发生了什么吗?

【问题讨论】:

  • MSDN ConcurrentBag&lt;T&gt;“表示线程安全、无序的对象集合。”。此集合类型中的顺序未指定。您观察到的行为纯属巧合。
  • @LucasTrzesniewski:在多线程中使用时,这里使用了contsructor。所以行为是确定性的。
  • @Frederick 今天可能是确定性的,但我的观点是,由于它被记录为无序,因此在框架的未来版本中,实现可能随时发生变化。您不应依赖未记录的行为。
  • 我认为添加一个线程始终是确定性的,因为 ConcurrentBag 使用的列表很少,每个线程一个。在一个线程中,插入值的最简单方法是确定性的。我认为这不会改变。

标签: c# mysql sorting linq-to-entities


【解决方案1】:

here

ConcurrentBag 似乎被实现为堆栈而不是 队列。也就是说,最后添加的项目是删除的第一个项目。一世 不过,不会指望这一点。

所以它们是以相反的顺序添加的。但是,ConcurrentBag 中的顺序并不意味着可靠一致,因此不能保证始终以这种方式运行,尤其是在被多个线程访问的情况下。

如果您关心保持原来的输入顺序,那么您可能需要ConcurrentQueue

【讨论】:

  • 来源Reference Source
  • 是的,这就是答案。谢谢!我什至没有教过堆栈。我认为这些信息应该出现在 msdn 网站上。我知道ConcurrentBag 在排序问题时不好,正如我在帖子中提到的那样,我不关心原始顺序。这篇文章是出于我的好奇心:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-11
  • 1970-01-01
相关资源
最近更新 更多