【问题标题】:LINQ List Initializer not keeping order from initializationLINQ 列表初始化程序不保持初始化顺序
【发布时间】:2012-02-16 11:30:03
【问题描述】:

我有以下问题: 我从数据库中选择数据,并为表中的每个项目创建一个模型。 该模型包含一个列表,其中包含 3 种语言的名称。 但由于某种原因,LINQ 没有保持我的列表初始化顺序。

代码:

db.SA_BamaType
            .Select(b => new BamaTypeModel()
            {
                id = b.p_bamatype,
                bamatypeNames = new List<string>()
                {b.bamatypeafdrukNL, b.bamatypeafdrukFR, b.bamatypeafdrukEN}
            }).ToList();

但是当我调试这个列表时,我看到这些项目是从位置随机切换的。 EN 将变为索引 0,而 NL 应为索引 0。

字典是最好的用途,但似乎 LINQ 无法翻译字典,这就是我使用 List 的原因。

【问题讨论】:

  • 您可以转换成字典。请参阅ToDictionary() method... 此外,当您从数据库中检索行时,除非您在特定键(或键组)上具有聚集索引,或者在处理结果集之前对结果集进行排序,否则无法保证顺序。跨度>
  • 可能无法保证来自数据库的订单。但是 List() 应该保证按传递的顺序存储项目!奇怪。
  • 确实很奇怪。重要的不是行的顺序,而是我在列表初始化程序中分配的项目的顺序,这似乎失去了它们的顺序。我现在使用字典,这实际上是这种情况下最好的方法,但我仍然不明白为什么列表不想保持我初始化的项目的顺序。

标签: c# linq list


【解决方案1】:

但似乎 LINQ 无法翻译字典

当然可以:

db.SA_BamaType
            .AsEnumerable()
            .Select(b => new BamaTypeModel()
            {
                id = b.p_bamatype,
                bamatypeNames = new Dictionary<string, string>
                {
                    { "NL", b.bamatypeafdrukNL },
                    { "FR", b.bamatypeafdrukFR },
                    { "EN", b.bamatypeafdrukEN }
                }
            }).ToList();

【讨论】:

  • 谢谢!缺少的是 .AsEnumerable(),这使得使用带有初始化程序的字典成为可能。
  • 顺便说一句,分析这一点,当使用带有字典而不是简单列表的 .AsEnumerable() 时,我得到了 +15 秒的页面加载差异。感兴趣的人为什么:在 .Where() 之前使用 .AsEnumerable() 将整个表加载到内存中,然后执行 where。这会导致更多的负载。更多信息:stackoverflow.com/questions/3311244/…
  • @Mortana,加载内存中所有数据的是 ToList,而不是 AsEnumerable。 AsEnumerable 的作用是将表视为 IEnumerable 而不是 IQueryable,以便查询的其余部分在内存中(逐行)执行,而不是翻译成 SQL。
【解决方案2】:
var items = db.SA_BamaType
        .Select(b => 
        {
            id = b.p_bamatype,
            NL =  b.bamatypeafdrukNL,
            EN =  b.bamatypeafdrukEN,
            FR =  b.bamatypeafdrukFR
        }).ToList();
var models = items.Select(b=>
    new BamaTypeModel()
    { 
        id = b.id,
        bamatypeNames = new List<string>()
            {b.NL, b.FR, b.EN} 
    }
).ToList();

小提示:new List() {..,..} 不是 LINQ2SQL 可以转换为 SQL 语句的构造,所以不能在 LINQ 查询中使用它。如果它对您有用,那么您可能已经将查询转换为对象(正如您在调用 AsEnumerable() 时注意到的那样)。
而 new List() {"A","B"} 等价于:

var list = new List<string>();
list.Add("A");
list.Add("B");

所以它应该保持声明顺序(“A”应该在位置0,“B”应该在位置1)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多