这个问题纯粹是学术性的,因为我从未想过会在真正的代码中这样做。
使用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可以做什么。
修改 我也试过禁用延迟加载,但没有影响。
答案 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();
}
就这样做吧