简体   繁体   中英

Entity Framework, Updating a record issue

I've been looking around but can't seem to find a solution. I'm not sure why, but db.SaveChages() is not saving the changes to database.

What I am trying to do is to increment the views counter by 1.

PictureViewCounter first calls the GetSinglePicture which returns the picture record.

PictureHelper.PictureViewCounter(PictureHelper.GetSinglePicture(userID,pic), (List<int>)Session["ViewedPictures"], pic);

PictureViewCounter first calls the GetSinglePicture which returns the picture properties.

public static Picture GetSinglePicture(int userID, int picture)
    {
        DBContext db = new DBContext();

        return (from p in db.Pictures
                where userID == p.UserID && picture == p.Url
                select p).First();
    }

PictureViewCounter then iterates through the array of pictureArray and sees if there is a match, if no match, increment the picture.Views.

        public static void PictureViewCounter(Picture picture, List<int> pictureArray, int pictureUrl)
    {
        PetscoveryDBContext db = new PetscoveryDBContext();
        if (pictureArray == null)
        {
            //Automatically +1 picture views
            picture.Views++;
            db.SaveChanges(); //does not save
        }
        else
        {
            int result = pictureArray.Find(pic => pic == pictureUrl);
            //if result == 0 increase picture views by 1
            picture.Views++;
            db.SaveChanges(); //does not save
        }
    }

It works when debugging, the Views do get incremented, just not saved. It's probably something VERY simple.

Thanks

The Picture entity comes from a different context ( DBContext ), and you're doing db.SaveChanges on a different context ( PetscoveryDBContext ).

hence the changes are not saved to the database.

they need to be in the same context, or you need to use the Attach method.

Also, your code doesn't dispose connections earlier. a slightly refactored method would be:

public static void UpdatePictureViewCounter(int userId, List<int> pictureArray, 
                                            int pictureUrl)
{
    if (pictureArray == null || !pictureArray.Contains(pictureUrl))
    {
        // increment the view.

        using (var db = new PetscoveryDBContext())
        {
            var picture = (from p in db.Pictures where userID == 
                          p.UserID && pictureUrl == p.Url select p).First();
            ++picture.Views;

            db.SaveChanges();
        }
    }
}

with the above code, we don't even query the database if not needed. and when the conditions are met, we query the DB, get the Picture entity, update it, save it back and dispose the connection.

Based on the code I see, it appears that your Picture instance came from a different PetscoveryDBContext . When you retreive an object from a context, that context tracks the changes made to that instance for you so that when you call SaveChanges it knows what update statements to issue to the database.

In this case you've created a new context and so it has no idea (probably about that Picture instance at all) what has changed or how to issue update commands.

I would suggest looking at this post: Save detached entity in Entity Framework 6 for more information.

You are saving the changes in the wrong context so EF isn't tracking the picture object. I would refactor your code slightly:

public static Picture UpdatePictureViews(int userID, int picture)
{
    DBContext db = new DBContext();

    var picture =  (from p in db.Pictures
                    where userID == p.UserID && picture == p.Url
                    select p).First();

    if(PictureViewCounter(picture, pictureArray, pictureUrl))
    {
        picture.Views++;
        db.SaveChanges();
    }
}

public static bool PictureViewCounter(Picture picture, List<int> pictureArray, int pictureUrl)
{
    //In here basically return true if you want to increase the view count
    if (pictureArray == null)
    {
        //Automatically +1 picture views
        return true;
    }
    else
    {
        int result = pictureArray.Find(pic => pic == pictureUrl);
        //if result == 0 increase picture views by 1
        return true;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM