Отношение не может быть изменено. Свойства внешнего ключа не могут иметь значение null

1

Я пытаюсь обновить объект типа MamConfiguration_V1

который exsit уже в DB

В нем имеется несколько ссылочных элементов (среди них MamConfigurationToBrowser_V1)

  private void UpdateEfItem(MamConfiguration_V1 itemFromDb, MamConfiguration_V1 itemFromUi)
    {
        itemFromDb.UpdatedDate = DateTime.Now;

        itemFromDb.Description = itemFromUi.Description;

        itemFromDb.StatusId = itemFromUi.StatusId;

        itemFromDb.Name = itemFromUi.Name;

        itemFromDb.NumericTraffic = itemFromUi.NumericTraffic;

        itemFromDb.PercentageTraffic = itemFromUi.PercentageTraffic;

        itemFromDb.Type = itemFromUi.NumericTraffic;


        itemFromDb.MamConfigurationToBrowser_V1.Clear();



        for (int i = 0; i < itemFromUi.MamConfigurationToBrowser_V1.Count; i++)
        {
            var elementToAdd = itemFromUi.MamConfigurationToBrowser_V1.ElementAt(i);

            elementToAdd.Browser = mMaMDBEntities.Browsers.Single(browserItem => browserItem.BrowserID == elementToAdd.BrowserID);

            elementToAdd.MamConfiguration_V1 = itemFromDb;

            itemFromDb.MamConfigurationToBrowser_V1.Add(elementToAdd);
        }

}

Я получаю следующую ошибку времени выполнения DB:

Операция завершилась неудачно: отношение не может быть изменено, поскольку одно или несколько свойств внешнего ключа не имеют значения NULL. Когда происходит изменение отношения, соответствующее свойство внешнего ключа устанавливается равным нулевому значению. Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, для свойства внешнего ключа должно быть назначено другое ненулевое значение, или не связанный с ним объект должен быть удален.

Но это странно. Все ссылки не являются нулевыми:

Изображение 174551

Изображение 174551

Upadte 2:

Я пробовал этот код:

        try
        {
            item.ThrowIfNull("item");

            var itemFromDB = GetById(item.ConfigurationId);

            if (itemFromDB != null)
            {
                UpdateEfItem(itemFromDB, item);

                //mMaMDBEntities.MamConfiguration_V1.Detach(itemFromDB);

                //mMaMDBEntities.MamConfiguration_V1.Attach(item);

                //mMaMDBEntities.ObjectStateManager.ChangeObjectState(item, System.Data.EntityState.Modified);

                //mMaMDBEntities.ObjectStateManager.ChangeObjectState(itemFromDB, System.Data.EntityState.Modified);


                mMaMDBEntities.SaveChanges();

                return item;
            }

}

        private void UpdateEfItem(MamConfiguration_V1 itemFromDb, MamConfiguration_V1 itemFromUi)
        {
            itemFromDb.UpdatedDate = DateTime.Now;
            itemFromDb.Description = itemFromUi.Description;
            itemFromDb.StatusId = itemFromUi.StatusId;
            itemFromDb.Name = itemFromUi.Name;
            itemFromDb.NumericTraffic = itemFromUi.NumericTraffic;
            itemFromDb.PercentageTraffic = itemFromUi.PercentageTraffic;
            itemFromDb.Type = itemFromUi.NumericTraffic;

            foreach (var item in itemFromDb.MamConfigurationToBrowser_V1.ToList())
            {
                if (itemFromUi.MamConfigurationToBrowser_V1.All(b => b.BrowserVersionId != item.BrowserVersionId))
                {
                    mMaMDBEntities.MamConfigurationToBrowser_V1.DeleteObject(item);
                }
            }

            for (int i = 0; i < itemFromUi.MamConfigurationToBrowser_V1.Count; i++)
            {
                var element = itemFromUi.MamConfigurationToBrowser_V1.ElementAt(i);
                var item = itemFromDb.MamConfigurationToBrowser_V1.SingleOrDefault(b => b.BrowserVersionId == element.BrowserVersionId);
                if (item != null)
                {
                    // copy properties from element to item
                }
                else
                {
                    element.Browser = mMaMDBEntities.Browsers.Single(browserItem =>
                        browserItem.BrowserID == element.BrowserID);

                    element.MamConfiguration_V1 = itemFromDb;

                    //have also tried: element.MamConfiguration_V1 = null;

                    //element.MamConfiguration_V1Reference = null;

                    itemFromDb.MamConfigurationToBrowser_V1.Add(element);
                }
            }
        }

и выполните эту ошибку:

{ "Нарушение ограничения UNIQUE KEY" UQ_MamConfigurations_V1 ". вставить дубликат ключа в объект 'dbo.MamConfiguration_V1'. дублирующее значение ключа (elad_14Apr_1315).\r\nПриложение было прекращается." }

Теги:
entity-framework

1 ответ

3
Лучший ответ

Эта строка...

itemFromDb.MamConfigurationToBrowser_V1.Clear();

... не только очистит коллекцию, но также установит ссылку из отдельных элементов в коллекции родительскому itemFromDb на null. Что изменение этих элементов и EF будет пытаться сохранить их в базе данных. Он терпит неудачу, потому что (возможно) ссылка нужна и не может быть null.

Вы должны использовать другой подход, который обновляет элементы коллекции поочередно. Вы должны учитывать, что элементы могли быть удалены в пользовательском интерфейсе, чтобы они могли быть изменены и что новые элементы могли быть добавлены. Он будет выглядеть примерно так:

private void UpdateEfItem(MamConfiguration_V1 itemFromDb,
    MamConfiguration_V1 itemFromUi)
{
    itemFromDb.UpdatedDate = DateTime.Now;
    itemFromDb.Description = itemFromUi.Description;
    itemFromDb.StatusId = itemFromUi.StatusId;
    itemFromDb.Name = itemFromUi.Name;
    itemFromDb.NumericTraffic = itemFromUi.NumericTraffic;
    itemFromDb.PercentageTraffic = itemFromUi.PercentageTraffic;
    itemFromDb.Type = itemFromUi.NumericTraffic;

    foreach (var item in itemFromDb.MamConfigurationToBrowser_V1.ToList())
    {
        if (!itemFromUi.MamConfigurationToBrowser_V1.Any(b =>
            b.BrowserID == item.BrowserID)
        {
            mMaMDBEntities.Browsers.DeleteObject(item);
        }
    }

    for (int i = 0; i < itemFromUi.MamConfigurationToBrowser_V1.Count; i++)
    {
        var element = itemFromUi.MamConfigurationToBrowser_V1.ElementAt(i);
        var item = itemFromDb.MamConfigurationToBrowser_V1
            .SingleOrDefault(b => b.BrowserID == element.BrowserID);
        if (item != null)
        {
            // copy properties from element to item
        }
        else
        {
            element.Browser = mMaMDBEntities.Browsers.Single(browserItem =>
                browserItem.BrowserID == element.BrowserID);

            itemFromDb.MamConfigurationToBrowser_V1.Add(element);
        }
    }
}
  • 0
    Я получаю эту ошибку на mMaMDBEntities.SaveChanges(); : {"Нарушение ограничения UNIQUE KEY 'UQ_MamConfigurations_V1'. Невозможно вставить повторяющийся ключ в объект 'dbo.MamConfiguration_V1'. Значение дублирующегося ключа равно (elad_14Apr_1315). \ R \ nОписание завершено."}
  • 0
    @EladBenda: есть ли у элементов в коллекции itemFromUi.MamConfigurationToBrowser_V ссылка на MamConfigurations_V1 ? Это было бы проблемой, потому что EF попытается вставить их вместе с новыми предметами.
Показать ещё 18 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню