【问题标题】:Complex object in grid view网格视图中的复杂对象
【发布时间】:2012-09-02 16:16:39
【问题描述】:

我有一个gridview,它的数据源是以下函数:

public static List<Train> GetTrainsByIDs(int [] ids) {
    using (var context = new MyEntities()) 
    {
        return ids.Select(x => context.Trains.Single(y => y.TrainID ==x)).AsQueryable().Include(x=>x.Station).ToList();
    }
}

网格视图的 ItemTemplate 为 &lt;%# Eval("Station.Name") %&gt;。 尽管我使用了 include 方法,但这会导致错误 The ObjectContext instance has been disposed and can no longer be used for operations that require a connection

当我将功能更改为

public static List<Train> GetTrainsByIDs(int [] ids) {
    using (var context = new MyEntities()) 
    {
        return context.Trains.Where(x => ids.Contains(x.TrainID)).Include(x=>x.Station).ToList();
    }
}

它工作正常,但是它们以错误的顺序出现,而且如果我有 2 个相同的 ID,我希望列表中有 2 个相同的火车。

除了创建一个新的视图模型,我还能做些什么吗?感谢您的帮助

【问题讨论】:

    标签: c# entity-framework gridview lazy-loading


    【解决方案1】:

    至于第一个查询:那是延迟执行。您创建了Trains 的IEnumerable,注意到它没有Include 方法,因此将其转换为IQueryable,添加了Include 并添加ToList() 以防止延迟加载。

    但是根据MSDN on DbExtensions.Include:

    此扩展方法调用 IQueryable 源对象的 Include(String) 方法(如果存在此类方法)。如果源 IQueryable 没有匹配的方法,那么这个方法什么都不做。

    (强调我的)

    选择的结果是IEnumerable 转换为IQueryable,但现在由EnumerableQuery 实现,而EnumerableQuery 没有实现Include。什么都没有发生。

    现在数据进入了试图显示车站的网格,这会在上下文消失时触发延迟加载。

    除此之外,这种设计还有另一个缺陷:它分别为每个 id 触发一个查询。

    所以第二个查询要好得多。这是一个查询,包括Stations。但是现在顺序是由数据库返回的顺序决定的。你可以使用Concat 来解决这个问题:

    IQueryable<Train> qbase = context.Trains.Include(x=>x.Station);
    IQueryable<Train> q = null;
    
    foreach (var id in ids)
    {
      var id1 = id; // Prevent modified closure.
      if (q == null)
        q = qbase.Where(t => t.Id == id1);
      else
        q = q.Concat(qbase.Where (t => t.Id == id1));
    }
    

    生成的查询不是很优雅(至少可以这么说),但毕竟它是一个查询而不是多个查询。

    【讨论】:

    • 想要重复 - 我写了 我想要列表中的 2 列相同的火车。顺序很重要——id 列表代表了人的旅程中的火车列表,并且必须以正确的顺序进行旅程。我必须做的是删除“使用”并依赖垃圾收集。
    • 是的,对不起,你的问题很清楚,我的头脑没有。我已经修改了关于第二个查询的答案。第一个查询的分析站。我会选择明确处理上下文的场景。
    • 谢谢,请看我的回答
    【解决方案2】:

    在阅读了@Gert Arnold 的回答并获得了分两个阶段执行此操作的想法后,我非常简单地使用了这样的第一个查询:

    using (context = new MyEntities())
    {
        var trns = context.Trains.Include(x => x.Station);
        return ids.Select(x => trns.Single(y => y.TrainID == x)).ToList();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 2019-04-10
      • 1970-01-01
      相关资源
      最近更新 更多