Reputation: 2287
I confused with error that Action returns me. I have a code in my manager:
public class AddressesManager
{
private SiteDBEntities entityContext;
public Addresses GetAddress(short id)
{
entityContext = new SiteDBEntities();
var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
entityContext.Dispose();
return addressList;
}
}
And action that call this function:
[HttpPost]
public ActionResult LoadAddress(short id)
{
AddressesManager mngr = new AddressesManager();
Addresses address = mngr.GetAddress(id);
return new JsonResult() { Data = address };
}
And jquery code wich call thit action:
$.post("/Cart/LoadAddress", { id: id })
.success(function (data) {
console.log(data);
})
.fail(function (e) { console.log(e) });
Action is running, but i always getting 500 error whit this code:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
As i understood the problem is with entityContext , but why this happens? I already executed data from DB and I don't need connection anymore...
EDIT:
Thit is my Address model. It autogenerated by EF:
public partial class Addresses
{
public int Id { get; set; }
public string Title { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string Warehouse { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public string Phone { get; set; }
public short DeliveryType { get; set; }
public System.Guid UserId { get; set; }
public virtual DeliveryType DeliveryType1 { get; set; }
public virtual Users Users { get; set; }
}
Upvotes: 2
Views: 2884
Reputation: 39326
If you want to use your entity data model then I suggest you to take a look to my answer in this post.
Now, what I would do is create a DTO to get only the data you need to pass to your View, like was proposed by @AnhTriet. To avoid map by yourself each property every time you need to project your query to your DTO, I suggest to use Automapper. Let me show you how would be your solution if you decide to use it:
public class AddressesManager
{
public Addresses GetAddress(short id)
{
using(var entityContext = new SiteDBEntities())
{
var address = entityContext.Addresses
.Where(a => a.Id == id)
.ProjectTo<AddressDTO>()
.FirstOrDefault();
return address;
}
}
}
About ProjectTo extension method.
Upvotes: 1
Reputation: 12085
The error happens because your Address
class has 2 virtual properties: DeliveryType1
and Users
.
When you convert your address
to JSON, it will try to access those virtual properties. However, at that time, your context are disposed already.
To avoid this problem, you shouldn't return the EF auto-generated class directly. Instead, create a DTO object (Data Transfer Object) containing only some fields you need, map it with the EF object, and return it. For example:
public class AddressesDTO
{
public int Id { get; set; }
public string Title { get; set; }
public string State { get; set; }
public string Country { get; set; }
public string Warehouse { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public string Phone { get; set; }
public short DeliveryType { get; set; }
public System.Guid UserId { get; set; }
}
Then, map it:
public Addresses GetAddress(short id)
{
entityContext = new SiteDBEntities();
var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
// Create DTO object
AddressesDTO address = new AddressesDTO();
// Map it
address.Id = addressList.Id;
address.Title = addressList.Title
// Go on, it's quite long...
entityContext.Dispose();
return address;
}
However, as you can see, the mapping process is very boring. A better way is using Automapper.
Upvotes: 1
Reputation: 92
When you are returning a json record in MVC you need to add AllowGet like so in your controller:
return Json(new { data= address }, JsonRequestBehavior.AllowGet);
With this in place you should be fine.
Upvotes: 0
Reputation: 2800
Addresses should be lazy-loaded in your case. So you are trying to access disposed data and Entity Framework tries to use disposed context and that gives an exception.
Maybe you need to attach your addressList to current context in order to enable lazy-loading
var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault();
entityContext.Addresses.Attach(addressList);
Upvotes: 0
Reputation: 14995
I think you should add attribute [JsonIgnore] to virtual properties of Addresses Class.
class Addresses
{
public int ID { get; set; }
[JsonIgnore]
public virtual Something Something { get; set; }
}
Upvotes: 0
Reputation: 6246
Do you have a navigation (child) property in your Address class? I get the feeling that you're trying to access this child property after the DbContext has been disposed of, as child properties are lazy-loaded by default.
Can you post the code of your Address model?
Upvotes: 0