【发布时间】: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<int> 和 2 个List<int>。我对此的期望是 1 和 3 将相同,2 和 4 也将相同。检查我得到了什么值:
ConcurrentBag<int> 的升序排序实际上是降序。在 Microsoft 网站上,我们可以读到,ConcurrentBag 在排序无关紧要时很好,但正如我们在 bagDesc 中看到的那样,保留了排序。为了表明我在数据库中没有任何奇怪的东西,我还创建了两个List<int>,其中排序保持应有的状态。
在我的数据库中执行 select * from produkt 会得到排序为 listAsc 和 bagDesc 的值。
数据库是mssql 2014,numerProduktu是这个表的主键。
有人知道那里发生了什么吗?
【问题讨论】:
-
MSDN
ConcurrentBag<T>:“表示线程安全、无序的对象集合。”。此集合类型中的顺序未指定。您观察到的行为纯属巧合。 -
@LucasTrzesniewski:在多线程中使用时,这里使用了contsructor。所以行为是确定性的。
-
@Frederick 今天可能是确定性的,但我的观点是,由于它被记录为无序,因此在框架的未来版本中,实现可能随时发生变化。您不应依赖未记录的行为。
-
我认为添加一个线程始终是确定性的,因为 ConcurrentBag 使用的列表很少,每个线程一个。在一个线程中,插入值的最简单方法是确定性的。我认为这不会改变。
标签: c# mysql sorting linq-to-entities