代码之家  ›  专栏  ›  技术社区  ›  Phil Wright

LINQ to Entities是否重用对象实例?

  •  1
  • Phil Wright  · 技术社区  · 16 年前

    使用LINQtoEntities听起来是查询数据库和获取实际的CLR对象(我可以修改这些对象)、数据绑定等等的一种很好的方法。但是,如果我第二次执行相同的查询,我是返回对同一个CLR对象的引用还是一个全新的集合?

    我不希望多个查询生成越来越多的相同实际数据的副本。这里的问题是,我可以更改一个实体的内容并将其保存回数据库,但是该实体的另一个实例仍然存在于其他地方,并且保存着旧数据。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Jon Skeet    16 年前

    在同一个DataContext中,我的理解是,对于返回完整对象而不是投影的查询,总是会得到相同的对象。

    但是,不同的数据上下文将获取不同的对象-因此有可能在那里看到过时的数据,是的。

        2
  •  1
  •   user35910    16 年前

    在同一个DataContext中,如果查询了相同的对象,则会得到相同的对象(DataContext为此维护内部缓存)。

    请注意,您处理的对象很可能是可变的,因此您可以获得另一个(并发访问),而不是一个问题(重复数据)。

    根据业务案例的不同,可以让第二个带有过时数据的事务在提交时失败。

    另外,想象一个好的旧的idataReader/dataset场景。两个查询将返回两个不同的读取器,它们将填充不同的数据集。因此,重复数据问题不是ORM特有的。

        3
  •  0
  •   Marc Gravell    16 年前

    [很抱歉,请注意,此回复适用于linq to sql,而不是实体框架。]

    我把它放在这里(而不是删除),因为它部分是关于主题的,可能有用。


    对于其他回复,请注意,数据上下文还能够避免对简单的“按主键”查询执行往返操作-它将首先检查缓存。

    不幸的是, completely 在3.5中损坏,并且仍然 half-broken 在3.5sp1中,但它适用于 一些 查询。如果要获取单个对象,这可以节省很多时间。

    所以基本上,IIRC需要使用:

    // uses object identity cache (IIRC)
    var obj = ctx.Single(x=>x.Id == id);
    

    但不是:

    // causes round-trip (IIRC)
    var obj = ctx.Where(x=>x.Id == id).Single();