将 GridView 绑定到 IQueryable

发布于 2024-10-20 12:06:30 字数 979 浏览 6 评论 0原文

这个问题纯粹是学术性的,因为我从来没有梦想过用真实代码来做到这一点。

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

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

下面是我使用 LINQ to SQL 获取 IQueryable 的代码:

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 的代码。

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

那么为什么这不起作用呢?我可以只使用 .ToList(),返回它,绑定到它,然后它就可以工作,但为什么 IQueryable 不能以相同的方式工作?我真正想要实现的是了解 IQueryable 的功能。

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

This question is purely academic, because I'd never dream of doing this in real code.

Using LINQ to SQL, I want to bind an IQueryable<T> to a GridView. I tried doing this with the following code, but I get the exception:

Cannot access a disposed object.
Object name: 'DataContext accessed after Dispose.'.

Here is my code that gets an IQueryable<tabGenre> using LINQ to SQL:

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

And here is my code that binds the GridView to the returned IQueryable<T>.

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

So why doesn't this work? I could just a .ToList<tabGenre>(), return it, bind to it and then it would work, but why doesn't IQueryable work in the same fashion? What I'm really trying to achieve here is an understanding of what IQueryable can do.

EDIT:
I also tried disabling lazy loading, but to no affect.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半夏半凉 2024-10-27 12:06:30

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

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

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

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

You can think of the IQueryable as the instructions required to execute the query. When you call .ToList(), you are executing the IQueryable() to return actual data. When you bind to IQueryable(), it will expect to have a data source to get the actual data whenever DataBind() is called.

When you set gvGenre.DataSource() = Genre.GetGenres2(), the DataContext required to get actual data based on your IQueryable is destroyed before the call to DataBind() occurs.

It works if you call .ToList() because you're physically going out and getting the data, then putting it memory.

Storing the IQueryable is like storing just the query. You can't execute a query if the datasource it expects to work with doesn't exist.

音盲 2024-10-27 12:06:30

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

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

解决这个问题的方法是去掉 using 块,或者强制 iq 在块内进行计算(例如 iq = iq.ToList()),并仅返回该评估的结果。如果您不热衷于后者,请放弃使用。 ctx 将在没有人需要后的某个时刻被处置。也许并不完美,但这就是垃圾收集器的生活。您确定如果它继续存在就会产生问题吗?不要修复尚未显示出损坏的东西。

The sole effect of that using block is to limit the lifespan of ctx to the block itself.

The useful lifespan of iq is dependent on the lifespan of ctx. You are explicitly disposing of ctx before iq is ever used.

The way to fix the problem would be to get rid of the using block, or to force iq to evaluate within the block (e.g. iq = iq.ToList()), and return only the results of that evaluation. If you're not keen on doing the latter, just ditch the using. ctx will be disposed of at some point after nobody needs it. Not perfect, maybe, but that's life with a garbage collector. Are you sure it'll be creating a problem if it stays around? Don't fix what's not yet shown to be broken.

行至春深 2024-10-27 12:06:30
    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();
}

就这样做

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

Just do it like this

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文