2

My MVC5 project View makes an api call to api/movies where the following logic exists:

(First, this is how the moviesDto is instantiated):

var moviesQuery = _context.Movies.Include(m => m.Genre);
var moviesDto = moviesQuery.ToList()
            .Select(Mapper.Map<Movie, MovieDto>);

And here's the logic:

//for regular API call add N/A to items that are not available
    foreach (MovieDto movie in moviesDto)
    {
        if (movie.NumberAvailable == 0)
                movie.Name = movie.Name + " N/A. :(";
    }
    return Ok(moviesDto);

I inspect the movie object(s) at run-time IN THE Foreach LOOP in debug mode and indeed find that the name property for some movies has "N/A :(" appended to it. But in the view, only the movie's (original) name appears.

Edit: On inspection of the moviesDto on the last line above line just before it is returned to caller, I find that the relevant movies' names have not been updated.

FWIW, This is the movieDto class definition:

public class MovieDto
    {
        public int Id { get; set; }

        [Required]
        [StringLength(100)]
        public string Name { get; set; }

        [Required]
        public byte GenreId { get; set; }

        public GenreDto Genre { get; set; }

        public DateTime ReleaseDate { get; set; }

        public DateTime DateAdded { get; set; }

        [Range(1, 25)]
        public byte NumberInStock { get; set; }

        public byte NumberAvailable { get; set; }
    }
PakiPat
  • 1,020
  • 14
  • 27
  • Are you clicking a button or something to call into the api or is the api code supposed to execute on page load? – chris-crush-code May 08 '17 at 20:10
  • 3
    http://shouldiblamecaching.com/ – GSerg May 08 '17 at 20:15
  • @chris-crush-code: on page load. And It has nothing to do with the DataTable. In fact, on inspection of the moviesDto list just before it is returned to the caller, I find that the rlevant movie names are NOT updated. – PakiPat May 08 '17 at 20:30
  • @chris-crush-code: on page load. And It has nothing to do with the DataTable. In fact, on inspection of the moviesDto list just before it is returned to the caller, I find that the rlevant movie names are NOT updated. – PakiPat May 08 '17 at 20:31
  • What is `moviesDto`? Is it an `IEnumerable`? An `IQueryable`? Please add relevant code on how you construct the `moviesDto` object. – Federico Dipuma May 08 '17 at 20:55
  • @FedericoDipuma: Sorry. Yes, it's an IEnumerable. – PakiPat May 08 '17 at 21:07
  • Please show how is created, I strongly believe this is the issue. – Federico Dipuma May 08 '17 at 21:10
  • @GSerg: Forgive my ignorance, but what cache? I cleared the client-side cache, but this is on the server side. – PakiPat May 08 '17 at 21:10
  • @PatrickGomes The browser cache. I posted that before you observed it does not change before returning from the controller. – GSerg May 08 '17 at 21:13
  • @FedericoDipuma : Have edited the question. Also, am looking for the equivalent of an SQL UPDATE method for Linq.. – PakiPat May 08 '17 at 21:20

1 Answers1

5

Your issue arises from the use of an IEnumerable (due to LINQ deferred execution ) and is caused by the fact that your moviesDto object is effectively a LINQ query.

Each time moviesDto is enumerated the query is executed again and the objects are picked up from the source (each time mapping again your materialized entities to new DTOs).

To resolve, just turn your collection into a list before manipulating it:

var moviesDto = moviesQuery.ToList()
        .Select(Mapper.Map<Movie, MovieDto>).ToList();
Federico Dipuma
  • 17,655
  • 4
  • 39
  • 56
  • I know "thanks" are discouraged here, but that really was an excellent explanation! – PakiPat May 08 '17 at 21:31
  • 2
    To get my head around this behaviour, I have created a Fiddle, demonstrating it: https://dotnetfiddle.net/iKjVkW - in case anyone else needs to see this in action... – J.N. May 08 '17 at 21:53