views:

35

answers:

2

I'm having a bit of trouble trying to add an object to the database using LINQ to SQL.

I have three tables in my database:

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


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


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

A Show has many Events, and each Event has many Attendees.

I have a page where I'm creating a Show. On the page, I'm adding Events to the Show, and Attendees to each Event, and then saving the show all at once.

Here is my code:

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();

The issue occurs in the second foreach loop. If I take it out, the Show and ShowEvents get added to the database correctly.

What's the issue here?

EDIT for Jay:

I've tried this now:

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

But I get the same error on that last line. Going through the debugger, ShowEventID is no longer 0, but I'm getting the same error.

+1  A: 

This is more of a database design issue. You should let the database handle data entry ID assignments.

If you are running Sql Server, go to your table design view, right click on the ID column and make this your primary key. Now look at the column properties. Set Identity Specification to yes. You can set the ID seed and Increment to whatever you want.

Now, when you run your updates, don't update the ID column, just the other data fields. Let the database worry about ID assignments.

When you enter a ShowEvent, have your Sql Method return a scalar value using "SELECT @@IDENTITY;" that represents the ID of the newly entered ShowEvent. Now, you can use this ID value to enter your Attendees, matching them to your ShowEvent ID. Make sure you perform the same Primary Key setup that I mentioned for your EventAttendees table. That way you are sure all of your attendees ID's are unique when they match up to the ShowEvent ID. Again, you shouldn't have to explicitly enter the Attendee ID. You should only have to enter the Foreign key value for the ShowEvent and match it to the Attendee data.

Not sure if that's clear, but if you need me to, I'll try to come up with some code.

-Matt

mledbetter
I have done that, the first column in my diagram above is the primary key for each table. And I'm not setting those IDs at all.
Steven
When you enter your showEvents, you aren't getting your @@IDENTITY value back correctly. I've had a similar issue, and trying to find exactly what I did to correct it. :-)
mledbetter
+1  A: 

When you call ShowEventID = ev.ShowEventID, it is always 0 because no ID has been assigned.

Since you are probably using identity fields as your primary key identifiers, you'll have to save the show (with its ShowEvents) in order to have IDs assigned to those on those ShowEvents.

After that, the second loop will work.

Alternatively, if you store a reference to the actual ShowEvent object in ShowEventAttendee, (an association in LINQ-to-SQL) instead of using the integral identifier, you would call ShowEvent = ev and you could save everything at once.

update

Something is off. Every time you loop you are adding attendees to the same ShowEvent, a local variable called showEvent. I would have assumed the intent here to be adding attendees for each of the ShowEvents of show, so should showEvent be replaced with ev?

Jay
I made an edit but I'm still getting the same error, take a look and see if you can see what the issue is.
Steven
@Steven What, exactly, *is* the error you're getting?
Jay
System.Data.Linq.DuplicateKeyException: Cannot add an entity with a key that is already in use.
Steven
@Steven I added an update.
Jay
Ack, sorry, that was a typo within my post. Yes, it should be adding attendees to ev. I've fixed my post.
Steven
@Steven I'm at a bit of a loss. I'd try commenting out `ShowEventID = ev.ShowEventID` or just adding a single attendee to a single ShowEvent to try to simplify and zero in on the issue.
Jay
Finally did some digging, and it turns out my ShowEventsAttendee primary key wasn't set to increment on every add :) So it was always 0, hence the error. Thanks for the help though.
Steven