locked
Why db.SaveChanges() does not work? RRS feed

  • Question

  • Hello,

    Please dig into the following piece of code to tell why db.SaveChanges() does not save records to the database:

    [HttpPost]
            [ValidateAntiForgeryToken]
            public ActionResult Index(vmJPP model)
            {
                
                if (ModelState.IsValid)
                {
                    if (regUser.UserName != "demo")
                    {
                        
    
                        foreach (var item in model.Records.ToList())
                        {
                            if (item.IsSelected == true)
                            {
                                Jeevan thisJeevan = db.Jeevans.Find(item.Id);
                                var pensionerId = thisJeevan.PensionerId;
    
                                Jeevan newJeevan = new Jeevan();
                                newJeevan.PensionerId = pensionerId;
                                newJeevan.Date = DateTime.Now;
    
                                int thisMonth = DateTime.Now.Month;
    
                                DateTime ValidThis = DateTime.Parse("31/10/" + DateTime.Now.Year);
                                DateTime ValidNext = DateTime.Parse("31/10/" + (DateTime.Now.Year + 1));
    
                                if (thisMonth == 11 || thisMonth == 12)
                                {
                                    newJeevan.ValidTill = ValidNext;
                                }
                                else
                                {
                                    newJeevan.ValidTill = ValidThis;
                                }
    
                                db.Jeevans.Add(newJeevan);
                                db.SaveChanges();
    
    
                            }
    
                        }
    
                        
    
                    }
                    else
                    {
                        Session["dispMsg"] = "Sorry! You are attempting something you don't have credentials for.";
                        return RedirectToAction("MsgSystem");
                    }
                }
    
                return RedirectToAction("Index");
              
            }

    Regards,

    Arun


    Monday, March 26, 2018 5:44 PM

Answers

  • Hello Zhanglong,

    Finally, I managed to resolve the issue and I'm regretful for troubling you guys. Actually, the issue was nither because of disconnected state of EF nor that the controller was doing data and business logic or that anything was not correct with the connecting string.

    It occurred simply because of the passing of the wrong id, which in turn resulted in saving the record for another id. Then, obviously, it would not return updated record for the corresponding id resulting in a false impression that db.SaveChanges() failed without throwing an exception.

    Regards,

    Arun

    Tuesday, March 27, 2018 1:05 PM

All replies

  • The only reason is that EF doesn't know the state of the object, because EF is in a disconnected state.

    https://www.c-sharpcorner.com/UploadFile/d87001/connected-and-disconnected-scenario-in-entity-framework/

    Secondly, the controller is doing database and business logic.

    https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs


    <copied>


    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.+

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained
    in the model.+

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder

    <end>

    Monday, March 26, 2018 7:36 PM
  • Hi ArunKhatri,

    Based on your code snippets, it seems ok, does it throw any exception? please check if your connection string is right.

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, March 27, 2018 1:21 AM
  • Hello Zhanglong,

    Thanks for responding. As it doesn't throw any exception it makes difficult to understand why it doesn't save changes to the database. As far as connection string is concerned, since rest of the things are working fine, I suppose there should not be any issue with it. As suggested by DA924x, I also tried putting the below piece of code into a separate class as a public void but things remain the same.

    Jeevan newJeevan = new Jeevan();
                                newJeevan.PensionerId = pensionerId;
                                newJeevan.Date = DateTime.Now;
    
                                int thisMonth = DateTime.Now.Month;
    
                                DateTime ValidThis = DateTime.Parse("31/10/" + DateTime.Now.Year);
                                DateTime ValidNext = DateTime.Parse("31/10/" + (DateTime.Now.Year + 1));
    
                                if (thisMonth == 11 || thisMonth == 12)
                                {
                                    newJeevan.ValidTill = ValidNext;
                                }
                                else
                                {
                                    newJeevan.ValidTill = ValidThis;
                                }
    
                                db.Jeevans.Add(newJeevan);
                                db.SaveChanges();

     Please help me find a solution to it.

    Regards,

    Arun

    Tuesday, March 27, 2018 2:54 AM
  • Hi ArunKhatri,

    >>I also tried putting the below piece of code into a separate class as a public void but things remain the same.

    Please check if your connection string's database is the same with your opened database. if the issue still exists, could you please create a simple with database, which could reproduce the issue via OneDrive.

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, March 27, 2018 2:59 AM
  • As suggested by DA924x, I also tried putting the below piece of code into a separate class as a public void but things remain the same.

    My main suggestion is to set the object's state to "Add".

    My second suggest is about who is in charge (architecture),  and it is not the controller. It's the model object that is in charge. The controller's job is about flow-control.

    As you see the controller example as you see no database logic in the controller.

    using System;
    using System.Linq;
    using System.Web.Mvc;
    using MVC.Models;
    using Microsoft.AspNet.Identity;
    
    namespace MVC.Controllers
    {
        public class ProjectController : BaseController
        {
            // GET: Project
            [Authorize]
            public ActionResult Index()
            {
                return View(new ProjectModels().GetProjectsByUserId(User.Identity.GetUserId()));
            }
    
            [Authorize]
            public ActionResult Details(int id = 0)
            {
                return id == 0 ? null : View(new ProjectModels().Edit(id));
            }
    
            [Authorize]
            public ActionResult Create()
            {
                return View(new ProjectModels().Create());
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Create(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                ValidateddlProjectTypes();
    
                project.ProjectType = (Request.Form["ddlProjectTypes"]);
    
                if (new ModelsHelper().IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(string.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(new ProjectModels().PopulateSelectedList(project));
    
                new ProjectModels().Create(project, User.Identity.GetUserId());
                return RedirectToAction("Index");
            }
    
            [Authorize]
            public ActionResult Edit(int id = 0)
            {
                return id == 0 ? null : View(new ProjectModels().Edit(id));
            }
    
            [Authorize]
            [HttpPost]
            public ActionResult Edit(ProjectViewModels.Project project, string submit)
            {
                if (submit == "Cancel") return RedirectToAction("Index");
    
                if (new ModelsHelper().IsEndDateLessThanStartDate(project, "Project"))
                    ModelState.AddModelError(String.Empty, "End Date cannot be less than Start Date.");
    
                if (!ModelState.IsValid) return View(new ProjectModels().PopulateSelectedList(project));
    
                var theproject = new ProjectViewModels.Project();
    
                theproject = project;
    
                theproject.ProjectType = Request.Form["ProjectType"];
    
                new ProjectModels().Edit(theproject, User.Identity.GetUserId());
                return RedirectToAction("Index");
            }
    
            public ActionResult Delete(int id = 0)
            {
                if (id > 0) new ProjectModels().Delete(id);
    
                return RedirectToAction("Index");
            }
       
            public ActionResult Cancel()
            {
                return RedirectToAction("Index", "Home");
            }
    
            public ActionResult UploadFile(int id)
            {
                return RedirectToAction("UploadFile", "Upload", new { id = id, type = "PM" });
            }
    
            private void ValidateddlProjectTypes()
            {
                if (Request.Form["ddlProjectTypes"] == string.Empty)
                {
                    ModelState.AddModelError("ProjectType", "Project Type is required");
                }
                else
                {
                    foreach (var key in ModelState.Keys.ToList().Where(key => ModelState.ContainsKey(key)))
                    {
                        if (key == "ProjectType")
                            ModelState[key].Errors.Clear();
                    }
                }
            }
        }
    }

    Tuesday, March 27, 2018 7:00 AM
  • Hello Zhanglong,

    Finally, I managed to resolve the issue and I'm regretful for troubling you guys. Actually, the issue was nither because of disconnected state of EF nor that the controller was doing data and business logic or that anything was not correct with the connecting string.

    It occurred simply because of the passing of the wrong id, which in turn resulted in saving the record for another id. Then, obviously, it would not return updated record for the corresponding id resulting in a false impression that db.SaveChanges() failed without throwing an exception.

    Regards,

    Arun

    Tuesday, March 27, 2018 1:05 PM
  • Hi ArunKhatri,

    I am glad to know that you resolve the issue and thank you for sharing the solution, please mark it as answer, it will be beneficial who have the similar issue.

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, March 28, 2018 12:53 AM
  • Finally, I managed to resolve the issue and I'm regretful for troubling you guys. Actually, the issue was nither because of disconnected state of EF nor that the controller was doing data and business logic or that anything was not correct with the connecting string.

    You seem to not understand about architecting the solution, which was a side benefit of showing how things should be done. It's about not slamming it all into the controller where is doesn't belong about database access a business logic, because it's not the controller's job. That's the point of part of my posts.

    Understand it....

     https://en.wikipedia.org/wiki/Separation_of_concerns

    Wednesday, March 28, 2018 12:39 PM