Я пытаюсь обновить объект типа 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. Когда происходит изменение отношения, соответствующее свойство внешнего ключа устанавливается равным нулевому значению. Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, для свойства внешнего ключа должно быть назначено другое ненулевое значение, или не связанный с ним объект должен быть удален.
Но это странно. Все ссылки не являются нулевыми:
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Приложение было прекращается." }
Эта строка...
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);
}
}
}
mMaMDBEntities.SaveChanges();
: {"Нарушение ограничения UNIQUE KEY 'UQ_MamConfigurations_V1'. Невозможно вставить повторяющийся ключ в объект 'dbo.MamConfiguration_V1'. Значение дублирующегося ключа равно (elad_14Apr_1315). \ R \ nОписание завершено."}itemFromUi.MamConfigurationToBrowser_V
ссылка наMamConfigurations_V1
? Это было бы проблемой, потому что EF попытается вставить их вместе с новыми предметами.