【问题标题】:How to dispose data context after usage使用后如何处理数据上下文
【发布时间】:2011-02-21 16:53:01
【问题描述】:

我有一个从数据上下文返回 IQueryable 的成员类

    public static IQueryable<TB_Country> GetCountriesQ()
    {
        IQueryable<TB_Country> country;

        Bn_Master_DataDataContext db = new Bn_Master_DataDataContext();

        country = db.TB_Countries
            .OrderBy(o => o.CountryName);

        return country;
    }

如您所见,我不会在使用后删除数据上下文。因为如果我删除它,调用此方法的代码将无法使用 IQueryable(可能是因为延迟执行?)。如何强制立即执行此方法?所以我可以处理数据上下文..

谢谢你:D

【问题讨论】:

  • 别忘了标记你最喜欢的答案。

标签: asp.net datacontext iqueryable


【解决方案1】:

Codeka 给出的示例是正确的,我建议在表示层调用该方法时使用此代码编写代码。但是,处理 DataContext 类有点棘手,所以我想对此添加一些内容。

LINQ to SQL 生成的域对象(在您的情况下为 TB_Countries 类)通常包含对 DataContext 类的引用。延迟加载需要此内部引用。当您访问引用对象的实例列表(例如:TB_Country.States)时,LINQ to SQL 将为您查询数据库。延迟加载的列也会发生这种情况。

当您处理 DataContext 时,您会阻止它再次被使用。因此,当您像在示例中所做的那样返回一组对象时,不可能在 TB_Country 实例上调用 States 属性,因为它会抛出 ObjectDisposedException

这并不意味着你不应该处理DataContext,因为我相信你应该这样做。你应该如何解决这个问题取决于你选择的架构,但 IMO 你基本上有两个选择:

选项 1. 将 DataContext 提供给 GetCountriesQ 方法。 当您的方法是业务层中的内部方法并且它是更大(业务)事务的一部分时,您通常希望执行此操作。当您从外部提供 DataContext 时,它是在方法范围之外创建的,不应丢弃它。您可以将其配置在更高的层。在这种情况下,您的方法基本上如下所示:

public static IQueryable<TB_Country> GetCountriesQ(
    Bn_Master_DataDataContext db)
{
    return db.TB_Countries.OrderBy(o => o.CountryName);
}

选项 2。不要从 GetCountriesQ 方法返回任何域对象。 当方法在您的业务层中是公共的并且将由表示层调用时,此解决方案很有用。您可以将数据包装在特制对象(DTO)中,该对象仅包含数据,不包含对DataContext 的隐藏引用。通过这种方式,您可以完全控制与数据库的通信,并且可以按照您的方式处理 DataContext。我在 SO here 上写了更多关于他的文章。在这种情况下,您的方法基本上如下所示:

public static CountryDTO[] GetCountriesQ()
{
    using (var db = new Bn_Master_DataDataContext())
    {
        var countries;
            from country in db.TB_Countries
            orderby country.CountryName
            select new CountryDTO()
            {
                Name = country.CountryName,
                States = (
                    from state in country.States
                    order by state.Name
                    select state.Name).ToList();
            };

        return countries.ToArray();
    }
}

public class CountryDTO
{
    public string Name { get; set; }
    public List<StateDTO> States { get; set; }
}

正如您将阅读的 here,您可以做一些聪明的事情来减少使用 DTO 的痛苦。

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您可以将可查询对象转换为列表,如下所示:

    public static List<TB_Country> GetCountriesQ()
    {
        using(var db = new Bn_Master_DataDataContext())
        {
            return db.TB_Countries
                .OrderBy(o => o.CountryName).ToList();
        }
    }
    

    【讨论】:

    • +1 顺便说一下 Erwin,这里的 using 语句将负责处理数据上下文(该类实现 IDisposable)它释放 System.Data.Linq.DataContext 使用的所有资源。跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 2016-11-30
    • 2018-08-13
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多