序列在 System.Linq.Enumerable.Single[Tsource](IEnumerable'1 源)中不包含任何元素

问题描述 投票:0回答: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 为 null

为什么会这样?

c# openxml
1个回答
0
投票

有许多 Linq 扩展方法会在序列(例如,

IEnumerable<T>
)为空或不满足您通过调用该方法所做的断言的情况下引发异常。

如果您的序列不包含

恰好一个

 元素,
Single<TSource>() 将引发异常。因此,如果序列为空或包含多个元素,它会引发异常。这就是发生在你身上的事。给定标签值不存在
SdtElement

如果序列为空,

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

如果您不能保证您的序列非空,这意味着它将准确包含或至少包含一个

SdtElement

,您应该使用 
SingleOrDefault<TSource>()
 或潜在的 
FirstOrDefault<TSource>()
如果序列为空,

SingleOrDefault<TSource>()

不会抛出异常,但如果序列包含多个元素,则会抛出异常。因此,它期望
最多一个元素。

FirstOrDefault<TSource>()

在任何情况下都不会抛出。如果 
null
 实例序列为空,它将返回 
SdtElement
。如果不为空,它将返回第一个
SdtElement
,忽略其他。因此,它需要
零个或更多元素。

© www.soinside.com 2019 - 2024. All rights reserved.