首页 > 解决方案 > 序列在 System.Linq.Enumerable.Single[Tsource](IEnumerable'1 源)中不包含任何元素

问题描述

我正在运行一些测试并使用 OpenXML 现在我想将数据放入一个数组并保存到它们各自的内容控件中。我试过了,我得到了这个执行

Sequence contains no Elements at System.Linq.Enumerable.Single[Tsource](IEnumerable'1 source)

使用此源代码:

using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PopulateContentsOpenXml
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string myfile = @"C:\Users\*****\Desktop\DTestDoc.docx";
            string[] writeDocData = new string[] {FirstName.Text,FileNumber.Text,IDNumber.Text,LastName.Text };
            WriteDataToContentControl(myfile, writeDocData);
        }

        private void WriteDataToContentControl(string filename,string[]data)
        {
            try
            {
                using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true))
                {
                    MainDocumentPart mainPart = doc.MainDocumentPart;
                    foreach (string text in data) 
                    {
                        SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).Single();
                        Text to = text_block.Descendants<Text>().Single();
                        to.Text = text;
                        mainPart.Document.Save();
                        MessageBox.Show("Ok i am fine now!");
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.ToString());
            }
        }
    }
}

我在第 39 行得到了异常,也就是这一行

SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).Single();

编辑 这样做

        SdtElement text_block = mainPart.Document.Body.Descendants<SdtElement>().Where(r => r.SdtProperties.GetFirstChild<Tag>().Val == text).SingleOrDefault();

        Text to = text_block.Descendants<Text>().Single();

我没有将对象设置为对象的实例。现在检查了,它说 text_block 为空

为什么会这样?

标签: c#openxml

解决方案


有许多 Linq 扩展方法会在序列(例如IEnumerable<T>)为空或不满足您通过调用该方法所做的断言的情况下抛出异常。

Single<TSource>()如果您的序列不包含恰好一个元素,则会引发异常。因此,如果序列为空或包含多个元素,则会引发异常。这就是发生在你身上的事情。没有 SdtElement那个给定的标签值。

First<TSource>()如果序列为空,Last<TSource>()也会抛出异常。他们期望序列中至少有一个元素。

如果您不能保证您的序列是非空的,这意味着它将完全包含或至少包含一个SdtElement,您应该使用SingleOrDefault<TSource>()or 潜在地FirstOrDefault<TSource>()

SingleOrDefault<TSource>()如果序列为空,则不会抛出,但如果它包含多个元素,则会抛出。因此,它最多期望一个元素。

FirstOrDefault<TSource>()在任何情况下都不会扔。null如果实例序列SdtElement为空,它将返回。如果它不为空,它将返回第一个SdtElement,忽略其他。因此,它期望零个或多个元素。


推荐阅读