【问题标题】:How do I return an IQueryable from Linq to SQL query when the dbContext is with a 'using' block?当 dbContext 带有“使用”块时,如何从 Linq 返回 IQueryable 到 SQL 查询?
【发布时间】:2011-04-12 15:03:48
【问题描述】:

我一直在使用“使用”块进行编码,但我想知道是否可以从以下返回 IQueryable,而无需在访问之前处理对象。

public IQueryable<Contact> GetContacts(string clientID)
{
    using (dbDataContext db = new dbDataContext())
    {
        var contacts = from _contacts in db.Contacts
                        where _contacts.ClientID == clientID
                        orderby _contacts.LastName ascending
                        select _contacts;

        return contacts;
    }
}

我是简单地删除“使用”块并让 .Net 管理对象,还是让 Linq 提前运行查询并返回填充的对象。

【问题讨论】:

  • 请注意,没有必要明确地处理数据上下文。无论如何,这是个好问题。
  • @fearofawhackplanet - 嗯,是的。 IMO 应假定任何一次性物品要求处置,并应妥善处理。它可以保持一个开放的连接,例如...
  • @Marc:我只是继续我在几个博客上阅读的内容,以及 ScottGu 和 Linq 团队的几乎所有示例。据我所知,微软的官方立场是,如果它能让你感觉更好,你可以处理,但这真的没有必要。请参阅 leedumond.com/blog/about-disposing-the-datacontext 作为示例,了解有关 dispose 和此问题中描述的延迟执行问题的一些讨论。
  • Scott Guthrie: "Datacontext 对象实际上并没有打开任何与数据库的连接——因此您不必显式处理它。相反,它从连接池仅在需要时才返回,完成后立即返回。” 没有比这更高的权限了。
  • 对于任何寻找的人,这里是@fearofawhackplanet 发布的文章的更新链接:web.archive.org/web/20130702164240/http://leedumond.com/blog/…

标签: c# .net linq-to-sql


【解决方案1】:

如果您不希望进一步组合数据(在 db-server 上),那么:

return contacts.ToList().AsQueryable();

虽然在这种情况下我更愿意返回 IEnumerable&lt;Contact&gt;IList&lt;Contact&gt; 以使不可组合的性质显而易见。使用AsQueryable 方法,它仍然 可组合的,但它会通过LINQ-to-Objects 组合(所以它从数据库中获取记录之后)。

如果您确实希望进一步编写它,那么您应该将数据上下文(或者,如果可能,将上游IQueryable&lt;something&gt;)传递给方法,并让调用者处理生命周期:

public IQueryable<Contact> GetContacts(dbDataContext db, string clientID)
{
    return from _contacts in db.Contacts
           where _contacts.ClientID == clientID
           orderby _contacts.LastName ascending
           select _contacts;
}

【讨论】:

  • @IckleMonkey - concrete 类型在那里最重要,但IList&lt;T&gt; 的一个明显优势是它将公开.Count 等(和一个索引器) ,使访问更方便。但不管IList&lt;T&gt; vs IEnumerable&lt;T&gt;,它仍然一个List&lt;T&gt;,所以内存使用是独立的。或者更简洁的答案:使用IList&lt;T&gt;
【解决方案2】:

你能让上下文对象成为你的类的成员实例吗?如果可以的话,您将推迟运行查询的调用,直到您真正接触到您返回的 IQueryable 实例下的枚举器。这取决于你想做什么。你需要从这个方法返回 IQueryable,还是可以用 IEnumerable 来做?

【讨论】:

  • 我想我会使用 IEnumerable,如果我使用成员实例方法,那么如果我的类用作“使用”块,我可能会遇到同样的问题,并且我想访问在此之外返回的数据。感谢您的建议。
【解决方案3】:

IQueryable 结果集中的联系人对象实例将保留在 using 块中使用的 datacontext 的引用,并将在客户端代码中按预期工作。您将能够对生成的 IQueryable 实例执行延迟 SQL 操作,并照常执行其他 IQueryable 操作。

【讨论】:

  • 当我尝试时,我得到“Dispose 后访问的 DataContext”。
【解决方案4】:

你可以这样做

public IQueryable<Contact> GetContacts(string clientID)
{
    IQueryable contacts;
    using (dbDataContext db = new dbDataContext())
    {
        contacts = from _contacts in db.Contacts
                        where _contacts.ClientID == clientID
                        orderby _contacts.LastName ascending
                        select _contacts;


    }

    return contacts;
}

【讨论】:

  • 这无济于事 - 延迟执行 LINQ 查询意味着在基础查询上调用 GetEnumerator() 之前很久,db-context 仍然被释放。所以没有工作人员。
猜你喜欢
  • 2013-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-02
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多