【问题标题】:ToDictionary error with LINQ [duplicate]LINQ 的 ToDictionary 错误 [重复]
【发布时间】:2018-06-16 14:16:42
【问题描述】:

我无法将这些表达式转换为 lambdas 而没有错误(无法转换类型错误):

var excel = new ExcelQueryFactory(@"E:\MAHipotCepaStationProgram.xlsx");

//get list of program names
List<string> testNames = new List<string>();
testNames.AddRange(excel.Worksheet().ToList()
            .Where(s => s["Program #"].Value.ToString() == "Program Title")
            .Select(s => s[1].Value.ToString()));


//get list of program numbers
List<int> testNumbers = new List<int>();
testNumbers.AddRange(excel.Worksheet().ToList()
            .Where(s => s["Program #"].Value.ToString() == "Program #")
            .Select(s => Convert.ToInt32(s[1].Value)));

//combine them
Dictionary<int, string> programs = new Dictionary<int, string>();
for (int x = 0; x < testNames.Count-1; x++)
{
    if (!programs.ContainsKey(Convert.ToInt32(testNumbers[x])))
    {
        programs.Add(Convert.ToInt32(testNumbers[x]), testNames[x]);
    }
    else
    {
        testNumbers[x].Dump("Duplicate Found");
    }
}

我们应该查看类似以下的内容,但无论我尝试什么,它都无法编译:

Dictionary<string, string> programsDict = excel.Worksheet().ToDictionary(
                                        e => e["Program #"].Value.ToString() == "Program Title")
                                            .Select(s => s[1].Value.ToString()),
                                        f => f.Where(d => d.Value.ToString() == "Program #").ToString());

非常感谢任何帮助。另外,这里是我们试图从中提取数据的 Excel 表的图片,即节目标题和节目编号。

【问题讨论】:

  • 看看 LINQ 中的Zip 方法。如果您添加 Excel 工作表外观的图像,可能有更好的方法,您可以在一个步骤中获取两个值,而不是使用匿名类型或元组在 ToDictionary 调用之前捕获这两个值。跨度>
  • @Ian Mercer - 好的,电子表格已添加。真的很好奇 Zip 如何在这里与 ToDictionary 调用一起工作......
  • 错误是什么?
  • "Cannot apply indexing to the Cell"是编译的错误
  • @ian mercer var zip = testNames.Zip(testNumbers, (code, state) => code + ": " + state);给我一个 IEnumberable 字符串,我将如何获得 IEnumberable 字符串?

标签: c# linq lambda extension-methods linq-to-excel


【解决方案1】:

这是创建数据透视表的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

            List<string> columnHeaders = excel.Worksheet.Select(x => (string)x[0]).ToList();
            columnHeaders = columnHeaders.Distinct().ToList();

            DataTable pivotTable = new DataTable();
            foreach (string columnHeader in columnHeaders)
            {
                if(columnHeader != "")
                   pivotTable.Columns.Add(columnHeader, typeof(string));
            }

            DataRow newRow = null;
            foreach (var row in excel.Worksheet)
            {
                if ((string)row[0] == "Program #")
                {
                    newRow = pivotTable.Rows.Add();
                }
                if((row[0] != null) && ((string)row[0] != ""))
                   newRow[(string)row[0]] = (row[1] == null) ? "" : row[1];  
            }
        }
    }
}

【讨论】:

  • NotSupportedException:LinqToExcel 仅在将 Distinct() 方法映射到类并选择单个属性时才提供对它的支持。 [例如。 (从 excel.Worksheet() 中的行选择 row.FirstName).Distinct()] @jdweng​​span>
  • 那就分两步搞定!!!查看更新的代码。
  • 对象引用未设置为对象的实例。现在是我到达这一行时的错误: newRow[(string)row[0]] = row[1]; @jdweng 谢谢你的帮助!
  • 我更新了处理空值的代码。
【解决方案2】:

尝试以下:

            //first get programs and numbers
            var rows = excel.Worksheet.Where(x => (x[0].ToString() == "Program #") || (x[0].ToString() == "Program Title")).Select(x => new { ColA = x[0].ToString(), ColB = x[1].ToString() }).ToList();

            // now even entries are the numbers and the odd are the titles
            var programTitle = rows.Select((x, i) => new { itemNumber = i / 2, program = x }).GroupBy(x => x.itemNumber).Select(x => new { number = int.Parse(x.FirstOrDefault().program.ColB), title = x.LastOrDefault().program.ColB }).ToList();

            //now create your dictionary
            Dictionary<int, string> programs = programTitle.GroupBy(x => x.number, y => y.title)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

【讨论】:

  • 在使用 WorksheetNoHeader 时只能在 WHERE 子句中使用列索引是我在将 () 添加到 Worksheet 后使用该代码时遇到的错误
  • 你是个巫师!我现在不清楚如何检查重复键...
  • 你不能有重复的键,否则,你不能创建字典。如果您有重复的键,那么您需要使用 Dictionary> 然后将 y.FirstOrDefault() 更改为 y.List();
  • 使用您拥有的数据,最好创建一个数据透视表。所以程序编号是结果的第一列,标题第二列,步骤是其他列。
  • 您的字典已将键/值对与 OP 想要的交换了。
猜你喜欢
  • 2011-07-06
  • 2017-03-26
  • 2010-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多