Hardik Gondalia
Hardik Gondalia

Reputation: 3717

Unable to Savechanges in Entity Framework when Object return from another class

I was developing simple MVC application that update record from the database. I've used BAL and Controller to get record and update like below

Student.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1.DAL
{
    public class Student
    {
        DemoDatabaseEntities db = new DemoDatabaseEntities();
        public Student_Mast getStudentByID()
        {
            Student_Mast student = db.Student_Mast.Where(i => i.StudID == 1).FirstOrDefault();
            return student;
        }
    }
}

and StudentController.cs

public class UpdateController : Controller
{
    DemoDatabaseEntities db = new DemoDatabaseEntities();
    Student _bal = new Student();
    / GET: Update
    public ActionResult Index()
    {
        Student_Mast model = new Student_Mast();
        model = _bal.getStudentByID();
        model.First_Name = "Hardik";
        model.Last_Name = "Gondalia";
        db.SaveChanges();
        return View();
    }
}

But db.savechanges() doesn't update the record.
Instead of this if I update record like below, it works
StudentController.cs

public class UpdateController : Controller
{
    DemoDatabaseEntities db = new DemoDatabaseEntities();
    Student _bal = new Student();
    / GET: Update
    public ActionResult Index()
    {
        Student_Mast model = new Student_Mast();
        model = db.Student_Mast.Where(i => i.StudID == 1).FirstOrDefault();
        model.First_Name = "Hardik";
        model.Last_Name = "Gondalia";
        db.SaveChanges();
        return View();
    }
}

Upvotes: 1

Views: 1263

Answers (4)

hmnzr
hmnzr

Reputation: 1430

It is happening because _bal.getStudentByID(); is getting Student entity from another EF context and this entity is detached from db context.

You can attach entity to your context or pass existing context as a dependency to Student class

In first case, updated version of StudentController.cs will contain following code:

public class UpdateController : Controller
{
    DemoDatabaseEntities db = new DemoDatabaseEntities();
    Student _bal = new Student();
    / GET: Update
    public ActionResult Index()
    {
        Student_Mast model = new Student_Mast();
        model = _bal.getStudentByID();
        db.Entry(model).State = EntityState.Modified

        model.First_Name = "Hardik";
        model.Last_Name = "Gondalia";
        db.SaveChanges();
        return View();
    }
}

What happening in second case is already answered above

Upvotes: 1

ocuenca
ocuenca

Reputation: 39376

Your issue in your first example is because you're getting the student entity from a different data context instance. You have two options here, implement an Update method in your Student class to save changes in the same DbContext instance where the student entity comes from, which is a bad design, you shouldn't define these kind of methods in your entities (research about Repository and UnitOfWork patterns), or define the update in your controller as you try in your second example:

 var model = db.Student_Mast.FirstOrDefault(i => i.StudID == 1);
 model.First_Name = "Hardik";
 model.Last_Name = "Gondalia";
 db.SaveChanges();

Upvotes: 1

Lali
Lali

Reputation: 2866

Pass the same database entity class DemoDatabaseEntities to the Student class. Do like this instead

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace WebApplication1.DAL
{
    public class Student
    {
        DemoDatabaseEntities db;
        public Student(DemoDatabaseEntities _db)
        {
           this.db = _db
        }

        public Student_Mast getStudentByID()
        {
            Student_Mast student = db.Student_Mast
                             .Where(i => i.StudID == 1).FirstOrDefault();
            return student;
        }
    }
}

Now in StudentController you will do this

public class UpdateController : Controller
{
    DemoDatabaseEntities db = new DemoDatabaseEntities();
    Student _bal = new Student(db);
    / GET: Update
    public ActionResult Index()
    {
        Student_Mast model = new Student_Mast();
        model = _bal.getStudentByID();
        model.First_Name = "Hardik";
        model.Last_Name = "Gondalia";
        db.SaveChanges();
        return View();
    }
}

This is actually using of same database context object for both database operations, i.e to get students and to update back to db.

Upvotes: 1

Kevin Sijbers
Kevin Sijbers

Reputation: 834

Since you are retrieving the record from a different instance of your DbContext, it is unable to save it. The solution would be to add a constructor to your Student class that takes a DbContext instance and saves it to the variable you have.

public class Student
{
    private DemoDatabaseEntities db = null;

    public Student(DemoDatabaseEntities dbContext){
    {
        this.db = dbContext;
    }

    public Student_Mast getStudentByID()
    {
        Student_Mast student = db.Student_Mast.Where(i => i.StudID == 1).FirstOrDefault();
        return student;
    }
}

Upvotes: 1

Related Questions