1

我的代码是这样的:

    [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仍然是用实际值实例化的。我不知道延迟加载实际上意味着什么,但肯定发生了一些加载。但我仍然收到此错误:

ObjectContext 实例已被释放,不能再用于需要连接的操作。

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

有什么办法来处理这个?


好的,我找到了原因。User 类有一个导航属性 PINS。我读到有一个 Include 方法。但此特定方法不需要 PINS 属性。是否有一个排除方法?

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

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

1 回答 1

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

于 2013-11-04T06:10:39.713 回答