我有一个包含许多默认属性的数据库表(例如)。我想查询数据库并返回这些属性之一,然后能够在不修改源的情况下对返回的对象进行更改。
基本上,我希望能够在检索到后对defaultAttribute
进行更改,而不会影响_context.Attributes
中的值。
DefaultAttribute defaultAttribute = new DefaultAttribute();
defaultAttribute = _context.Attributes
.Where(u => u.Color == color && u.Size == _size)
.Select(u => u).First();
返回:
defaultAttribute.Color = "Black"
defaultAttribute.Size = "Small"
修改对象:
defaultAttribute.Color = "none";
defaultAttribute.Size = "none";
再次提交查询:
defaultAttribute = _context.Attributes
.Where(u => u.Color == color && u.Size == _size)
.Select(u => u).First();
返回:
defaultAttribute.Color = "none"
defaultAttribute.Size = "none"
但是我需要它返回未修改的值:
defaultAttribute.Color = "Black"
defaultAttribute.Size = "Small"
我不知道我是否解释得足够好。上面的代码是从我的头顶上写下来的,以说明我遇到的问题。
如何创建 DefaultAttribute 对象,从数据库中检索值并能够对 DefaultAttribute 进行更改,而不会影响从数据库返回的值?
.AsNoTracking() 将对象与实体上下文分离。
defaultAttribute = _context.Attributes
.Where(u => u.Color == color && u.Size == _size)
.Select(u => u).AsNoTracking().First();
此外,您可以在 where 子句之前直接在表对象本身上使用它:
defaultAttribute = _context.Attributes
.AsNoTracking()
.Where(u => u.Color == color && u.Size == _size)
.Select(u => u).First();
您将需要包含 System.Data.Entity
命名空间,在 Visual Basic 和 C# 中,您可以根据 [MSDN],在 IQueryable 类型的任何对象上调用此方法作为实例方法。
正如David L所提到的,您可以使用AsNoTracking()
来解决问题。
这是另一种方法:
defaultAttribute = _context.Set<Attribute>().AsNoTracking()
.Where(u => u.Color == color && u.Size == _size)
.Select(u => u).First();
这应该可以解决您遇到的另一个问题: .. no extension method 'AsNoTracking' accepting a first argument ..
。
您可能希望包含using System.Data.Entity;
,如果尚未包含