Столбец не позволяет DBNull.Value и Удалить не помогает. Почему? - PullRequest
0 голосов
/ 18 февраля 2020

Я получаю сообщение об ошибке:

Столбец «Код» не разрешает DBNull.Value

Вот мой код:

public async Task UpdateDBWithXML(XmlReader reader, string hashKey, string hash)
        {
            var table = new DataTable();
            table.Columns.Add("Code");
            table.Columns.Add("ShortName");
            table.Columns.Add("Name");
            table.Columns.Add("LegalAddress");
            table.Columns.Add("Status");

            using (var transaction = this.Context.Database.BeginTransaction(IsolationLevel.ReadUncommitted))
            using (var sqlBulk = new SqlBulkCopy((SqlConnection)this.Connection, SqlBulkCopyOptions.Default, transaction.UnderlyingTransaction as SqlTransaction))
            {
                this.Context.Database.ExecuteSqlCommand("DELETE FROM [dbo].[LegalContractors]");

                sqlBulk.DestinationTableName = "LegalContractors";

                string lastElement = null;
                DataRow lastRow = null;
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if(reader.Name == "RECORD")
                            {
                                if (table.Rows.Count > 0 && lastRow.IsNull("Code"))
                                { 
                                    table.Rows.Remove(lastRow); 
                                }
                                if (table.Rows.Count > 10000)
                                {
                                    await sqlBulk.WriteToServerAsync(table);
                                    table.Rows.Clear();
                                }

                                lastRow = table.Rows.Add();
                            }
                            lastElement = reader.Name;
                            break;
                        case XmlNodeType.Text:
                            ProcessList(lastElement, reader.Value, lastRow);
                            break;
                    }
                }

                if (table.Rows.Count > 0 && lastRow.IsNull("Code"))
                {
                    table.Rows.Remove(lastRow);
                }
                if (table.Rows.Count > 0)
                {
                    await sqlBulk.WriteToServerAsync(table);
                    table.Rows.Clear();
                }

                //update hash here

                transaction.Commit();
            }
        }

        private void ProcessList(string lastElement, string value, DataRow row)
        {
            switch (lastElement)
            {
                case "NAME":
                    row["Name"] = value;
                    break;

                case "SHORT_NAME":
                    row["ShortName"] = value;
                    break;

                case "EDRPOU":
                    row["Code"] = value;
                    break;

                case "ADDRESS":
                    row["LegalAddress"] = value;
                    break;

                case "STAN":
                    row["Status"] = value;
                    break;
            }
        }

Как вы видите, я удаляю DataRows с пустым «кодом». Почему может произойти ошибка? Должен ли я использовать другой API для удаления?

Я попробовал подход, предложенный в этом вопросе: используйте lastRow["Code"] == DBNull.Value вместо lastRow.IsNull("Code"). Это тоже не помогло.

Вот пример XML Я разбираю:

<?xml version="1.0" encoding="windows-1251"?>
<DATA FORMAT_VERSION="1.0">
    <RECORD>
        <NAME>МІЖНАРОДНА ГРОМАДСЬКА ОРГАНІЗАЦІЯ МІЖНАРОДНА АКАДЕМІЯ БІОЕНЕРГОТЕХНОЛОГІЙ</NAME>
        <SHORT_NAME>МАБЕТ</SHORT_NAME>
        <EDRPOU>00011601</EDRPOU>
        <ADDRESS>01001, м.Київ, Шевченківський район, ВУЛИЦЯ ПРОРІЗНА, будинок 8, офіс 426</ADDRESS>
        <BOSS>ТКАЧЕНКО ВОЛОДИМИР АНДРІЙОВИЧ</BOSS>
        <KVED>94.12 Діяльність професійних громадських організацій</KVED>
        <STAN>зареєстровано</STAN>
        <FOUNDERS>
            <FOUNDER>Члени організації, розмір внеску до статутного фонду - 0.00 грн.</FOUNDER>
        </FOUNDERS>
    </RECORD>
    <RECORD>
        <NAME>фоо</NAME>
        <SHORT_NAME>фоо короткое имя</SHORT_NAME>
        <EDRPOU></EDRPOU>
        <ADDRESS>фоо адрес</ADDRESS>
        <BOSS>фоо бос</BOSS>
        <KVED>фоо квед</KVED>
        <STAN>фоо состояние</STAN>
        <FOUNDERS>
            <FOUNDER>фоо организатор</FOUNDER>
        </FOUNDERS>
    </RECORD>
</DATA>

Ответы [ 2 ]

1 голос
/ 18 февраля 2020

Ваш XML не содержит столбец с именем code, а ProcessList () не создает его. Тем не менее, оно есть в определении вашей таблицы, поэтому может показаться, что оно всегда равно нулю.

Я подозреваю, что ваша SQL структура таблицы установила, что столбец Code не допускает нулевые значения, и поэтому обновление SQL выбрасывает ошибка.

Необходимо либо заполнить столбец «Код» чем-либо, либо установить для него значение null или иметь значение по умолчанию в базе данных.

1 голос
/ 18 февраля 2020

Вы можете разрешить DBNull для своего столбца code, создав новый DataColumn:

DataTable table = new DataTable();
DataColumn code = new DataColumn("code");
code.AllowDBNull = true;
table.Columns.Add(code);

Я надеюсь, что это поможет вам.

...