1

My application is meant to allow users to add upcoming events from a list to a personal calendar. The personal calendar is implemented as a single table, shared across all users, that links a string UserID value to an int EventID, with a separate int UserCalendarID for a primary key.

However, the table is not updating when the action is called; the action is posted below:

    [HttpPost]
    public IActionResult AddToCalendar(int ID)
    {
        var events = context.Events.ToList();
        Event _e = events.FirstOrDefault(x => x.EventID == ID);
        var calendars = context.Calendars.ToList();
        UserCalendar c = new UserCalendar
        {
            UserID = userManager.GetUserAsync(HttpContext.User).Result.UserName,
            EventID = _e.EventID
        };
        calendars.Add(c);
        context.SaveChanges();
        return View("Index");
    }

For reference, this is the (working) code to add an Event to the Events table:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> NewEvent(Models.NewEventViewModel model, string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        var newEvent = new Event {
            Artist = await userManager.GetUserAsync(HttpContext.User),
            EventName = model.EventName,
            Time = model.Time,
            Venue = model.Venue,
            GenreID = model.GenreID
        };
        var events = context.Events;
        events.Add(newEvent);
        context.SaveChanges();
        ViewBag.Notification = "Your event has been added.";
        ViewBag.Color = "Green";
    }
    else {
        ViewBag.Notification = "Something went wrong — Event not added.";
        ViewBag.Color = "Red";
    }
    return View("Index");
}

The reason I'm not using a ViewModel for AddToCalendar is that there's no view specifically for it; rather, it's triggered by a button in a form on the EventDetails page, which is defined as follows:

@model Event
@{ 
    ViewData["Title"] = "Event Details";
    Event e = ViewBag.Event;
}

<h2>@ViewData["Title"]</h2>

<p><b>Event Name: </b>@e.EventName</p>
<p><b>Artist: </b>@e.Artist.ClientName</p>
<p><b>Date and Time: </b>@e.Time</p>
<p><b>Genre: </b>@e.Genre.GenreName</p>
<p><b>Venue: </b>@e.Venue</p>

@if (ViewBag.isYours)
{
    <a asp-action="DeleteEvent" asp-controller="Home" class="btn btn-danger" [email protected]>DELETE</a>
    <a asp-action="EditEvent" asp-controller="Home" class="btn btn-success" [email protected]>EDIT</a>
}
<form asp-action="AddToCalendar" asp-controller="Home" [email protected] asp-route-returnurl="@ViewData["ReturnUrl"]">
    <input type="submit" value="Add To Your Calendar" class="btn btn-default" />
</form>

I have already confirmed that c is being added to calendars. Why does the AddToCalendar event not cause the table to update?

4
  • You are adding "c" to the list that is in memory and not the actual context of the database. Try using context.Calendars.Add(c). It should then update after your call to context.SaveChanges() Commented Dec 19, 2016 at 20:09
  • Sorry, I missed how you were using "Events" below that. If you want to use it the same way, you can just remove the ToList() from the line: var calendars = context.Calendars.ToList(). This should track the database context object instead of the list that is returned from ToList() Commented Dec 19, 2016 at 20:12
  • 1
    Your second option worked; would you consider posting it as an answer so I can accept it? Commented Dec 19, 2016 at 20:14
  • I will post it. Glad it worked! Commented Dec 19, 2016 at 20:16

1 Answer 1

1

Notice, when you are getting the Calendars from the database context, you are calling:

var calendars = context.Calendars.ToList();

this loads a List of UserCalendar objects into memory. This does not track the actual Calendars table in the database. When you are adding to your Events table you are getting the Events table object like this:

var events = context.Events;

Notice, there is no call to "ToList()", which means you are adding a reference to the actual context object of "Events", not just a list in memory.

If you remove the .ToList() from your call to get the calendars, it will track the database context object just as it does in your call to get the Events object. This should solve your problem.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.