将GridView绑定到IQueryable <t> </t>

时间:2011-03-04 17:24:56

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

这个问题纯粹是学术性的,因为我从未想过会在真正的代码中这样做。

使用LINQ to SQL,我想将IQueryable<T>绑定到GridView。我尝试使用以下代码执行此操作,但我得到了异常:

  

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

以下是使用LINQ to SQL获取IQueryable<tabGenre>的代码:

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<T>

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

那么为什么这不起作用?我只能.ToList<tabGenre>(),返回它,绑定它然后它会工作,但为什么IQueryable不能以同样的方式工作?我真正想要实现的是理解IQueryable可以做什么。

修改 我也试过禁用延迟加载,但没有影响。

3 个答案:

答案 0 :(得分:16)

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

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

如果你调用.ToList(),它会有效,因为你实际上是在外出并获取数据,然后把它放入内存。

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

答案 1 :(得分:2)

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

iq的有效寿命取决于ctx的生命周期。在ctx被使用之前,您明确地处置iq

解决问题的方法是摆脱使用区块,或强制iq在区块内进行评估(例如iq = iq.ToList()),并仅返回评估结果。如果你不热衷于做后者,那就放弃使用。在没人需要之后,ctx会被处理掉。也许并不完美,但这就是垃圾收集者的生活。如果它留在身边,你确定它会产生问题吗?不要修复尚未显示的内容。

答案 2 :(得分:0)

    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();
}

就这样做吧