2016-05-13 71 views
2

我对Action返回给我的错误感到困惑。我有我的经理代码:Json的实体框架模型结果

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; 
      } 
} 

和行动调用这个函数:

[HttpPost] 
     public ActionResult LoadAddress(short id) 
     { 
      AddressesManager mngr = new AddressesManager(); 
      Addresses address = mngr.GetAddress(id); 
      return new JsonResult() { Data = address }; 
     } 

和jQuery代码至极呼叫thit行动:

$.post("/Cart/LoadAddress", { id: id }) 
     .success(function (data) { 

      console.log(data); 
     }) 
    .fail(function (e) { console.log(e) }); 

行动正在运行,但我总是得到500错误惠特代码:

T他的ObjectContext实例已经处理完毕,不能再用于需要连接的操作。

据我所知,问题是与entityContext,但为什么会发生这种情况?我已经从执行DB数据,我也不需要连接了...

编辑:

Thit是我的地址模型。它由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; } 
    } 
+0

我查地址变量数据 - 一切OK现在和数据在这里 – dantey89

+0

发生这种错误,因为地址类有一定的虚拟性,并且将它转换成JSON,它要得到这些虚拟财产了。 – Kahbazi

+0

是的,你是对的。就是这个。那么避免这个错误的方法是什么?手动映射模型? – dantey89

回答

0

您的地址类中是否有导航(儿童)属性?在DbContext被处理后,我感觉你正试图访问这个子属性,因为默认情况下子属性是延迟加载的。

你能发表你的地址模型的代码吗?

+0

是一个在我的经理的析构函数中使用EFcontext.Dispose()以避免延迟加载的问题的良好做法? – dantey89

0

我想你应该将属性[JsonIgnore]添加到Addresses类的虚拟属性。

class Addresses 
{ 
    public int ID { get; set; } 

    [JsonIgnore] 
    public virtual Something Something { get; set; } 
} 
0

地址应该在您的情况下延迟加载。所以你试图访问处置的数据和实体框架试图使用处置的上下文,并给出一个例外。

也许你需要你的AddressList中附加到当前上下文,以使延迟加载

var addressList = entityContext.Addresses.Where(a => a.Id == id).FirstOrDefault(); 
entityContext.Addresses.Attach(addressList); 
0

当你在MVC返回JSON记录你需要添加AllowGet像这样在你的控制器:

return Json(new { data= address }, JsonRequestBehavior.AllowGet); 

有了这个,你应该没问题。

1

发生此错误是因为您的Address类具有2个虚拟属性:DeliveryType1Users

当您将address转换为JSON时,它将尝试访问这些虚拟属性。但是,那个时候,你的语境已经被处理了。

为避免此问题,您不应直接返回EF自动生成的类。相反,创建一个DTO对象(数据传输对象),仅包含您需要的一些字段,将其映射到EF对象并返回。例如:

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; } 
} 

然后,图吧:

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; 
} 

然而,正如你所看到的,映射过程是很枯燥的。更好的方法是使用Automapper

1

如果你想使用你的实体数据模型那么我建议你去看看我在这个post答案。

现在,我会做的是创建一个DTO只得到你需要传递给你的视图,如被提出@AnhTriet数据。为避免每次需要将您的查询投影到您的DTO时自己映射每个属性,我建议使用Automapper。让我告诉你,如果你决定使用它怎么会是你的解决方案:

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; 
     } 
    } 
} 

关于ProjectTo扩展方法。

+0

感谢您的信息。我目前正在学习课程,并且从小组的成员那里听说他们使用Automaper时表现不佳。所以他们决定使用自定义映射。 – dantey89

+0

你对DTO的评论对我来说是最有用的。现在我可以更清楚地了解程序架构 – dantey89

+0

不客气;)。关于Automapper,我必须说至少在我的情况下,我没有遇到过这样的问题。但我认为一切都取决于您创建查询的方式,因为最后会转换为SQL,如果您在Linq查询中执行效率低下的操作或映射不必要的数据,当然这会影响您的性能。 – octavioccl