【发布时间】:2008-11-11 07:49:05
【问题描述】:
使用 LINQ to Entities 听起来是一种很好的方式来查询数据库并获取我可以修改的实际 CLR 对象、数据绑定等等。但是,如果我第二次执行相同的查询,我会返回对相同 CLR 对象或全新集合的引用吗?
我不希望多个查询生成越来越多的相同实际数据的副本。这里的问题是我可以更改一个实体的内容并将其保存回数据库,但该实体的另一个实例仍然存在于其他地方并保存旧数据。
【问题讨论】:
使用 LINQ to Entities 听起来是一种很好的方式来查询数据库并获取我可以修改的实际 CLR 对象、数据绑定等等。但是,如果我第二次执行相同的查询,我会返回对相同 CLR 对象或全新集合的引用吗?
我不希望多个查询生成越来越多的相同实际数据的副本。这里的问题是我可以更改一个实体的内容并将其保存回数据库,但该实体的另一个实例仍然存在于其他地方并保存旧数据。
【问题讨论】:
在同一个 DataContext 中,我的理解是您将始终获得相同的对象 - 对于返回完整对象而不是投影的查询。
但是,不同的 DataContexts 将获取不同的对象 - 因此存在在那里看到陈旧数据的风险,是的。
【讨论】:
在同一个 DataContext 中,如果查询它,您将获得相同的对象(DataContext 为此维护内部缓存)。
请注意,您处理的对象很可能是可变的,因此您可以得到另一个问题(并发访问),而不是一个问题(数据重复)。
根据业务案例,让具有陈旧数据的第二个事务在提交时失败可能是可以的。
另外,想象一个很好的旧 IDataReader/DataSet 场景。两个查询将返回两个不同的读取器,它们将填充不同的数据集。所以数据重复问题不是 ORM 特有的。
【讨论】:
[哎呀;请注意,此回复适用于 Linq-to-SQL,而不适用于实体框架。]
我把它留在这里(而不是删除),因为它部分是关于主题的,并且可能有用。
关于其他回复,请注意,数据上下文还可以避免对简单的“按主键”查询进行往返 - 它会首先检查缓存。
不幸的是,它在 3.5 中被 completely 损坏,在 3.5SP1 中仍然是 half-broken,但它适用于一些查询。如果您要获取单个对象,这可以节省大量时间。
所以基本上,你需要使用 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();
【讨论】: