Последовательность не содержит элементов в System.Linq.Enumerable.Single [Tsource] (источник IEnumerable'1) - PullRequest
0 голосов
/ 21 января 2020

Я запускаю какой-то тест и использую Open XML, теперь я хочу получить данные в массив и сохранить их в соответствующие элементы управления контентом. Я пытался, и я получаю это исполнение

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 равен нулю

Почему это так?

1 Ответ

0 голосов
/ 21 января 2020

Существует ряд методов расширения Linq, которые выдают исключение в случае, если последовательность (например, IEnumerable<T>) пуста или не выполняет утверждение, которое вы делаете, вызывая этот метод.

Single<TSource>() сгенерирует исключение, если ваша последовательность не содержит ровно один элемент. Таким образом, он генерирует исключение, если последовательность пуста или содержит более одного элемента. Это то, что случилось с тобой. Нет SdtElement с данным значением тега.

First<TSource>(), и Last<TSource>() также вызовет исключение, если последовательность пуста. Они ожидают как минимум один элемент в последовательности.

Если вы не можете гарантировать, что ваша последовательность не пустая, то есть она будет содержать точно или хотя бы один SdtElement, вы следует использовать SingleOrDefault<TSource>() или потенциально FirstOrDefault<TSource>().

SingleOrDefault<TSource>() не будет выбрасывать, если последовательность пуста, но будет выбрасывать, если она содержит более одного элемента. Таким образом, он ожидает, что не более одного элемента.

FirstOrDefault<TSource>() не будет выбрасывать в любом случае. Он вернет null, если последовательность SdtElement экземпляров пуста. Если он не пустой, он вернет первый SdtElement, игнорируя остальные. Таким образом, он ожидает ноль или более элементов.

...