【问题标题】:Binding GridView to IQueryable<T>将 GridView 绑定到 IQueryable<T>
【发布时间】:2011-07-09 00:00:48
【问题描述】:

这个问题纯粹是学术问题,因为我从来没有想过在真实代码中这样做。

使用 LINQ to SQL,我想将 IQueryable&lt;T&gt; 绑定到 GridView。我尝试使用以下代码执行此操作,但出现异常:

无法访问已处置的对象。 对象名称:“Dispose 后访问的 DataContext。”。

这是我使用 LINQ to SQL 获取IQueryable&lt;tabGenre&gt; 的代码:

public static IQueryable<lu_Genre> GetGenres2() {
    using (BooksContextDataContext ctx = new BooksContextDataContext()) {
        IQueryable<tabGenre> iq = from g in ctx.tabGenre
                                  select g;
        return iq;
    }
}

这是我将 GridView 绑定到返回的IQueryable&lt;T&gt; 的代码。

private void GetGenres() {
    gvGenre.DataSource = Genre.GetGenres2();
    gvGenre.DataBind();
}

那么为什么这不起作用呢?我可以只是一个.ToList&lt;tabGenre&gt;(),返回它,绑定到它,然后它就可以工作了,但是为什么 IQueryable 不能以同样的方式工作呢?我在这里真正想要实现的是了解 IQueryable 可以做什么。

编辑: 我也尝试禁用延迟加载,但没有影响。

【问题讨论】:

    标签: linq-to-sql gridview asp.net-4.0 iqueryable


    【解决方案1】:

    您可以将 IQueryable 视为执行查询所需的指令。当您调用 .ToList() 时,您正在执行 IQueryable() 以返回实际数据。当您绑定到 IQueryable() 时,只要调用 DataBind(),它就会有一个数据源来获取实际数据。

    当您设置 gvGenre.DataSource() = Genre.GetGenres2() 时,根据您的 IQueryable 获取实际数据所需的 DataContext 在调用 DataBind() 之前被销毁。

    如果您调用 .ToList() 它会起作用,因为您实际上要出去获取数据,然后将其放入内存。

    存储 IQueryable 就像只存储查询一样。如果预期使用的数据源不存在,则无法执行查询。

    【讨论】:

    • 这对我来说非常有意义。我实际上必须向工作中的一些同行解释这一点,而您的解释是教科书,所以我会使用它。谢谢!!
    【解决方案2】:

    使用块的唯一作用是将ctx 的生命周期限制为块本身。

    iq 的使用寿命取决于ctx 的使用寿命。在使用iq 之前,您明确 处理了ctx。

    解决问题的方法是去掉 using 块,或强制 iq 在块内进行评估(例如 iq = iq.ToList()),并仅返回该评估的结果。如果您不热衷于后者,请放弃使用。 ctx 将在无人需要后的某个时候被处理掉。也许并不完美,但这就是垃圾收集器的生活。你确定如果它留下来会造成问题吗?不要修复尚未显示已损坏的内容。

    【讨论】:

    • 感谢您的意见。我知道,摆脱 Using 块确实可以解决问题。我试过了,它奏效了,但我不喜欢让 GC 为我清理 DataContext。实际上,我什至尝试在退货之前加载 IQ,希望它能够工作,但它没有。那时,我开始怀疑 IQ 可能会无限期地与 DataContext 绑定,但我想与 StackOverflow 的精明成员核实以确保。再次感谢。
    【解决方案3】:
        public IQueryable MembershipGetAll()
        {
    
    
                var obj = (from mem in db.GetTable<MEMBERSHIP>()
                               select new
                               {
                                   NAME = mem.MEMBERSHIP.NAME,
                                   TYPE = mem.MEMBERSHIP.TYPE,
                                   TAX_ID = mem.TAX_RATE.TAX_ID,
                                   DISCOUNT = mem.DISCOUNT,
                                   DISCOUNT_PERCENT = mem.DISCOUNT_PERCENT,
    
                               }
                              ).AsQueryable();
                return obj;
    
        }
    
    
    private void LoadMembership()
    {
        IQueryable mem = null;
        mem = eb.MembershipGetAll();
        grdMembership.DataSource = mem;
        grdMembershipRates.DataBind();
    }
    

    就这样吧

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 2018-09-16
      相关资源
      最近更新 更多