Невозможно добавить объект с ключом, который уже используется - PullRequest
1 голос
/ 15 сентября 2010

У меня возникли некоторые проблемы при попытке добавить объект в базу данных с помощью LINQ to SQL.

В моей базе данных три таблицы:

--------------------------------------------
tblShows
--------------------------------------------
ShowID  |  Name
--------------------------------------------


--------------------------------------------
tblShowEvents
--------------------------------------------
ShowEventID  |  ShowID  |  Name
--------------------------------------------


--------------------------------------------
tblShowEventAttendees
--------------------------------------------
ShowEventAttendeeID  |  ShowEventID  |  Name
--------------------------------------------

Шоу имеет много событий, а каждое событие имеет много участников.

У меня есть страница, на которой я создаю Шоу. На этой странице я добавляю события в шоу и участников к каждому событию, а затем сохраняю шоу сразу.

Вот мой код:

Show show = new Show();
show.Name = txtName.Text.Trim();

//add ShowEvents to Show
//showEventsList is a variable containing a List of ShowEvents
foreach (ShowEvent ev in showEventsList)
{
    show.ShowEvents.Add(new ShowEvent
    {
        ShowID = show.ShowID,
        Name = ev.Name
    });
}

//Add ShowEventAttendees to each ShowEvent
//attendeesList is a variable containing a List of ShowEventAttendees
foreach (ShowEvent ev in show.ShowEvents)
{
    foreach (ShowEventAttendee attendee in attendeesList)
    {
        ev.ShowEventAttendees.Add(new ShowEventAttendee
        {
            ShowEventID = ev.ShowEventID,
            Name = attendee.Name
        });
    }
}

AppDataContext.DataContext.Shows.InsertOnSubmit(show);
AppDataContext.DataContext.SubmitChanges();

Проблема возникает во втором цикле foreach. Если я уберу это, Show и ShowEvents будут правильно добавлены в базу данных.

В чем здесь проблема?

РЕДАКТИРОВАТЬ для Джея:

Я попробовал это сейчас:

AppDataContext.DataContext.Shows.InsertOnSubmit(show);
AppDataContext.DataContext.SubmitChanges();

//Add ShowEventAttendees to each ShowEvent
//attendeesList is a variable containing a List of ShowEventAttendees
foreach (ShowEvent ev in show.ShowEvents)
{
    foreach (ShowEventAttendee attendee in attendeesList)
    {
        ev.ShowEventAttendees.Add(new ShowEventAttendee
        {
            ShowEventID = ev.ShowEventID,
            Name = attendee.Name
        });
    }
}

AppDataContext.DataContext.SubmitChanges();  //trying to update, error here

Но я получаю ту же ошибку в последней строке. Проходя через отладчик, ShowEventID больше не равен 0, но я получаю ту же ошибку.

Ответы [ 2 ]

1 голос
/ 15 сентября 2010

Когда вы звоните ShowEventID = ev.ShowEventID, это всегда 0, потому что ID не был назначен.

Поскольку вы, вероятно, используете поля идентификаторов в качестве идентификаторов первичного ключа, вам нужно сохранить шоу (с его ShowEvents), чтобы идентификаторы были назначены для них в этих ShowEvents.

После этого будет работать второй цикл.

В качестве альтернативы, если вы храните ссылку на фактический объект ShowEvent в ShowEventAttendee (ассоциацию в LINQ-to-SQL) вместо использования интегрального идентификатора, вы вызываете ShowEvent = ev и можете сохранить все сразу.

обновление

Что-то выключено. Каждый раз, когда вы зацикливаетесь, вы добавляете посетителей к одной и той же ShowEvent, локальной переменной с именем showEvent. Я бы предположил, что намерение здесь будет добавлять участников для каждого из ShowEvents из show, поэтому showEvent следует заменить на ev?

1 голос
/ 15 сентября 2010

Это больше проблема дизайна базы данных. Вы должны позволить базе данных обрабатывать присвоения идентификаторов ввода данных.

Если вы работаете с Sql Server, перейдите к представлению «Дизайн таблицы», щелкните правой кнопкой мыши по столбцу ID и сделайте этот ключ первичным. Теперь посмотрим на свойства столбца. Установите Идентификационную спецификацию на да. Вы можете установить ID seed и Increment на все, что вы хотите.

Теперь, когда вы запускаете свои обновления, не обновляйте столбец ID, только остальные поля данных. Пусть база данных беспокоится о присвоении идентификаторов.

Когда вы вводите ShowEvent, ваш метод Sql возвращает скалярное значение, используя «SELECT @@ IDENTITY;» который представляет идентификатор недавно введенного ShowEvent. Теперь вы можете использовать это значение идентификатора для ввода ваших посетителей, сопоставляя их с вашим идентификатором ShowEvent. Убедитесь, что вы выполняете ту же настройку первичного ключа, которую я упоминал для вашей таблицы EventAttendees. Таким образом, вы уверены, что все ваши идентификаторы участников являются уникальными, если они совпадают с идентификатором ShowEvent. Опять же, вам не нужно явно вводить идентификатор посетителя. Вам нужно только ввести значение внешнего ключа для ShowEvent и сопоставить его с данными посетителя.

Не уверен, что это понятно, но если я понадоблюсь, я попытаюсь придумать какой-нибудь код.

Матф

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...