已经处理了ObjectContext实例,但我已经复制了该对象

时间:2013-11-03 13:52:58

标签: entity-framework linq-to-sql linq-to-entities

我的代码是:

    [HttpGet]
    public List<User> GetUsers()
    {
        List<User> Users;
        using (Entities db = new Entities())
        {
            var users = from u in db.Users select u;
            Users = users.ToList();
        }
        //XXX
        return Users;
    }

我在XXX处放置了一个断点,并确认对象Users仍然使用实际值进行实例化。我不知道Lazy Loading实际意味着什么,但肯定发生了一些加载。但我仍然得到这个错误:

  

ObjectContext实例已被释放,无法再使用   对于需要连接的操作。

为什么会这样?对象Users在using块之外声明,所以垃圾收集器是否应该跟踪对象是否仍在使用?

处理此问题的方法是什么?


好的,我找到了原因。 User类具有Navigation属性PINS。我读到有一个Include方法。但是在这种特定方法中不需要PINS属性。是否有排除方法?

我在return语句之前尝试了以下操作,但仍然存在相同的错误。

        foreach (var user in Users) user.PINS = null;

1 个答案:

答案 0 :(得分:0)

您可以创建DTO(数据传输对象),这是一个自定义C#类,仅包含您要序列化的属性。

[HttpGet]
public List<UserDTO> GetUsers()
{
    List<UserDTO> Users;
    using (Entities db = new Entities())
    {
        var users = from u in db.Users select u;
        Users = users.ToList().Select(x=> new UserDTO(x)).ToList();
    }
    //XXX
    return Users;
}

public class UserDTO{

    public UserDTO(User user){
        this.Username = user.Username;
        ...
    }

    public string Username {get;set;}
    ...
    // properties you want to serialize
    ...
}

此外,您的API实现不正确,

我建议使用以下模式,

 public class DataAPI : APIController{

     protected Entities DB { get; private set; };

     public DataAPI(){
         DB = new Entities();
     }

     // This ensures that your Context will live
     // till end of the request, so you will not
     // get dispose exception
     public override void Dispose(){
         DB.Dispose();
     }
 }

同时检查实体REST SDK,我已经为实体框架编写了REST SDK,它可能完成所有工作,包括安全上下文的概念,它允许根据登录的用户类型自动过滤实体并隐藏序列化属性

http://entityrestsdk.codeplex.com