将常量表行值与LINQ

时间:2017-02-22 10:32:21

标签: c# xml linq join

在以下链接Combine tables using row values as column LINQ C# SQL的基础上,我将使用行值作为列组合两个IEnumerables。与编写的不同,我不使用由Web服务获得的具有常量字段的表。

var element = XDocument.Parse(getstring1);

            var dataCode = from item in element.Descendants("Field")
                           where item.Element("Code").Value == "CODE"
                           select item.Element("Value");

            var dataDescription = from item in element.Descendants("Field")
                                  where item.Element("Code").Value == "DESCRIPTION"
                                  select item.Element("Value");

            var resultsSet = dataCode.Zip(dataDescription, Tuple.Create);

            element = XDocument.Parse(getstring2);

            var dataSizeSet = from item in element.Descendants("Field")
                              where item.Element("Code").Value == "SIZESET"
                              select item.Element("Value");

            var dataSizeId = from item in element.Descendants("Field")
                             where item.Element("Code").Value == "SIZEID"
                             select item.Element("Value");

            var dataSizeLabel = from item in element.Descendants("Field")
                                where item.Element("Code").Value == "SIZELABEL"
                                select item.Element("Value");

            var resultsLabel = dataSizeSet.ZipThree(dataSizeId, dataSizeLabel, Tuple.Create);

            var results = resultsSet.GroupJoin(resultsLabel,
                            set => set.Item1,
                            label => label.Item1,
                            (set, label) => new
                            {
                                set.Item1,
                                set.Item2,
                                Label01 = label.SingleOrDefault(x => x.Item2.Value == "1").Item3,
                                Label02 = label.SingleOrDefault(x => x.Item2.Value == "2").Item3,
                                Label03 = label.SingleOrDefault(x => x.Item2.Value == "3").Item3,
                                Label04 = label.SingleOrDefault(x => x.Item2.Value == "4").Item3,
                                Label05 = label.SingleOrDefault(x => x.Item2.Value == "5").Item3,
                                Label06 = label.SingleOrDefault(x => x.Item2.Value == "6").Item3,
                                Label07 = label.SingleOrDefault(x => x.Item2.Value == "7").Item3,
                                Label08 = label.SingleOrDefault(x => x.Item2.Value == "8").Item3,
                                Label09 = label.SingleOrDefault(x => x.Item2.Value == "9").Item3,
                                Label10 = label.SingleOrDefault(x => x.Item2.Value == "10").Item3,
                                Label11 = label.SingleOrDefault(x => x.Item2.Value == "11").Item3,
                                Label12 = label.SingleOrDefault(x => x.Item2.Value == "12").Item3,
                                Label13 = label.SingleOrDefault(x => x.Item2.Value == "13").Item3,
                                Label14 = label.SingleOrDefault(x => x.Item2.Value == "14").Item3,
                                Label15 = label.SingleOrDefault(x => x.Item2.Value == "15").Item3,
                                Label16 = label.SingleOrDefault(x => x.Item2.Value == "16").Item3,
                                Label17 = label.SingleOrDefault(x => x.Item2.Value == "17").Item3,
                                Label18 = label.SingleOrDefault(x => x.Item2.Value == "18").Item3,
                                Label19 = label.SingleOrDefault(x => x.Item2.Value == "19").Item3,
                                Label20 = label.SingleOrDefault(x => x.Item2.Value == "20").Item3
                            });

var"结果",如果我展开IEnumerable,什么都不包含,并得到以下错误信息:"对象引用未设置为对象的实例"。

有什么想法建议我吗?

2 个答案:

答案 0 :(得分:0)

您正在使用label.SingleOrDefault(),它可能返回null,然后在结果上调用.ItemN,这将导致'对象引用未设置为对象的实例'在那种情况下。

答案 1 :(得分:0)

您需要一个数据透视表。下面的代码使用第二个表格中的信息更新您的第一个表格。

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

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {
            DataTable personTbl = new DataTable();
            personTbl.Columns.Add("Id", typeof(int));
            personTbl.Columns.Add("Name", typeof(string));
            personTbl.Columns.Add("Age", typeof(int));

            personTbl.Rows.Add(new object[] { 1, "Steve", 21});
            personTbl.Rows.Add(new object[] { 2, "Jack", 17});
            personTbl.Rows.Add(new object[] { 3, "Alcice", 25});
            personTbl.Rows.Add(new object[] { 4, "Harry", 14});

            DataTable personInfo = new DataTable();
            personInfo.Columns.Add("UId", typeof(int));
            personInfo.Columns.Add("Key", typeof(string));
            personInfo.Columns.Add("Value", typeof(string));

            personInfo.Rows.Add(new object[] { 1, "Height", "70"});
            personInfo.Rows.Add(new object[] { 2, "Height", "65"});
            personInfo.Rows.Add(new object[] { 2, "Eyes", "Blue"});
            personInfo.Rows.Add(new object[] { 4, "Height", "51"});
            personInfo.Rows.Add(new object[] { 3, "Hair", "Brown"});
            personInfo.Rows.Add(new object[] { 1, "Eyes", "Green"});

            List<string> infoType = personInfo.AsEnumerable().Select(x => x.Field<string>("Key")).Distinct().ToList();

            foreach (string type in infoType)
            {
                personTbl.Columns.Add(type, typeof(string));
            }

            Dictionary<int, List<DataRow>> dict = personInfo.AsEnumerable().GroupBy(x => x.Field<int>("UId"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());

            foreach (DataRow row in personTbl.AsEnumerable())
            {
                int id = row.Field<int>("Id");
                if(dict.ContainsKey(id))
                {
                   List<DataRow> rowInfo = dict[id];
                   foreach (DataRow col in rowInfo)
                   {
                       row[(string)col["key"]] = col["Value"];
                   }
                }
            }
        }
    }
}