я после многих-To-Many отношения между двумя субъектами RelayConfig и StandardContactEntity Framework Обновление Многие-ко-многим - ПОКО
Entities:
public class RelayConfig : EntityBase, IDataErrorInfo {
...
//Associations
public virtual ICollection<StandardContact> StandardContacts { get; set; }
}
public class StandardContact :EntityBase, IDataErrorInfo {
...
//Associations
public virtual ICollection<RelayConfig> RelayConfigs { get; set; }
}
Теперь я Я пытаюсь обновить RelayConfig и его отношения с StandardContact. Вот код, который обновляет RelayConfig.
public class RelayConfigRepository : GenericRepository<RelayConfig> {
....
public void Update(RelayConfig relayConfig, List<StandardContact> addedContacts, List<StandardContact> deletedContacts) {
context.RelayConfigs.Add(relayConfig);
if (relayConfig.Id > 0) {
context.Entry(relayConfig).State = EntityState.Modified;
}
addedContacts.ForEach(ad => relayConfig.StandardContacts.Add(ad));
foreach (StandardContact standardContact in relayConfig.StandardContacts) {
if (standardContact.Id > 0) {
context.Entry(standardContact).State = EntityState.Modified;
}
}
relayConfig.StandardContacts.ToList().ForEach(s => {
if (deletedContacts.Any(ds => ds.Id == s.Id)) {
context.Entry(s).State = EntityState.Deleted;
}
});
}
...
}
Когда я запускаю обновление, я получаю исключение, внутреннее исключение которого приводится ниже.
InnerException: System.Data.SqlClient.SqlException
Message=Violation of PRIMARY KEY constraint 'PK__Standard__EE33D91D1A14E395'. Cannot insert duplicate key in object 'dbo.StandardContactRelayConfigs'.
dbo.StandardContactRelayConfigs является таблица связывания, которая связывает RelayConfig и StandardContact. Как вы можете видеть, код обновления изменяет все сущности на измененное состояние, если Id> 0 (кроме удаленных записей, которые установлены в конце метода Update).
Я действительно не могу понять, почему инфраструктура сущности пытается вставить строку в связанную таблицу и не удается выполнить вышеуказанное исключение. Я уже изменяю EntityState существующих объектов RelayConfig.StandardContacts для Modified.
Короче, почему я получаю исключение, вставленное выше.
приветствия, Nirvan.
Edit: Параметры, чтобы обновить метод выше (addedContacts и deletedContacts) уже существующие объекты с Id> 0.
edit2: В соответствии с вашими предложениями я удалил код для вставки свежий (не существует в базе данных) записей из метода обновления. Поэтому теперь мой метод обновления добавляет существующие записи StandardContact к коллекции RelayConfig. Но я все еще не могу заставить код работать правильно. Сначала вот код, который я использую
public void Update(RelayConfig relayConfig, List<StandardContact> addedContacts, List<StandardContact> deletedContacts) {
context.RelayConfigs.Add(relayConfig);
if (relayConfig.Id > 0) {
context.Entry(relayConfig).State = EntityState.Modified;
}
addedContacts.ForEach(contact => {
context.StandardContacts.Attach(contact);
relayConfig.StandardContacts.Add(contact);
objectContext.ObjectStateManager.
ChangeRelationshipState(relayConfig, contact, rs => rs.StandardContacts, EntityState.Added);
});
}
На данный момент я просто концентрируюсь на добавленных рекордах. Вышеприведенный код работает хорошо, когда StandardContact (контактная переменная) не имеет никаких связей с другими существующими объектами RelayConfig. В этом случае в таблице соединений создается новая запись для каждого контакта, добавленного в коллекцию RelayConfig.StandardContacts. Но все становится уродливым (непредсказуемое поведение), когда StandardContact (контактная переменная) уже находится в отношениях с другими объектами RelayConfig. В этом случае, когда StandardContact добавляется в RelayConfig.StandardContacts Collection, StandardContact также добавляется в базу данных, тем самым создавая дубликат записи. Кроме того, также создается новый объект RelayConfig (я не знаю откуда) и вставлен в таблицу RelayConfigs. Я действительно не могу понять, как структура сущности работает с отношениями «многие-ко-многим».
@Ladislav, если у вас есть пример кода, который работает с обновлениями отношений «Множество ко многим» (для отдельных объектов), я могу попросить вас, пожалуйста, показать мне то же самое.
С уважением, Nirvan
Edit3 (раствор):
В конце концов я закончил с использованием совершенно другой подход. Вот код для обновления
public void Update(RelayConfig relayConfig, List<StandardContact> exposedContacts) {
context.Entry(relayConfig).State = EntityState.Modified;
relayConfig.StandardContacts.Clear();
exposedContacts.ForEach(exposedContact => {
StandardContact exposedContactEntity = null;
exposedContactEntity = context.StandardContacts.SingleOrDefault(sc => sc.Id == exposedContact.Id);
if (exposedContactEntity != null) {
relayConfig.StandardContacts.Add(exposedContactEntity);
}
});
}
С уважением, Nirvan.
Благодарим за отзыв. Но у меня все еще есть сомнения. Предположим, что нет добавленных рекордов или удаленных рекордов. Предполагая, что RelayConfig имеет 2 записи StandardContact, и я хочу сохранить изменения в этих двух файлах StandardContact, нужно ли мне изменить состояние отношения этих двух стандартныхконтактов в дополнение к изменению их EntityState для изменения? Я имею в виду, как мы обновляем многие стороны отношений (пренебрегая добавленными и удаленными записями на данный момент). – Jatin
Если вы добавите realayConfig, вы должны изменить состояния отношений на неизмененные. Если вы просто Attache realayConfig, вам не нужно ничего делать с этими отношениями, но добавление может вызвать другие проблемы, если вы хотите добавить новые отношения. –
См. Мое редактирование с пометкой «Edit2»: – Jatin