如何停止跟踪/映射 EF 中的变量
本文关键字:变量 EF 映射 停止跟踪 | 更新日期: 2023-09-27 18:34:15
我有一个 EF Code First 表,其中包含我不想更改的数据,但我想将数据检索到几个彼此独立的变量。问题在于,对其中一个变量进行更改会更改另一个变量的值。
例如,定义了 EF 代码优先上下文:
public class MyVal {
public int id { get; set; }
public double SomeVal { get; set; }
}
使用数据填充表后:
context.MyVals.AddOrUpdate(new MyVal { SomeVal = 1 });
context.MyVals.AddOrUpdate(new MyVal { SomeVal = 2 });
context.MyVals.AddOrUpdate(new MyVal { SomeVal = 3 });
接下来,我执行一个查询:
List<MyVal> myvals = _context.MyVals.AsNoTracking().Where(d => d.SomeVal >= 0).Select(m => m).ToList();
上面的查询返回预期数据。如您所见,我已经指定了 AsNoTracking((。接下来,我想创建另一个我将修改的变量:
List<MyVal> myvals1 = myvals;
现在我想修改 myvals1 而不影响 myvals 中的任何值:
foreach (MyVal m in myvals1) {
m.SomeVal = m.SomeVal * 2;
}
myvals1 现在将包含 3 条具有以下值的记录:
2
4
6
问题是myvals也被更改为:
2
4
6
由于我在查询上下文时使用了 AsNoTracking((,我还需要做什么才能使这些变量彼此独立?为什么这些变量似乎被视为相同?
问题是你不是通过简单地分配给变量来创建新对象,因为对象 int c# 是通过引用而不是值传递的。因此,当您将myvals
分配给myvals1
时,您只需传递对同一对象的引用。因此,您需要创建一个新List
并使用它:
List<MyVal> myvals1 = new List<MyVal>(myvals);
如果您需要从另一个对象创建MyVal
对象,有多种解决方案,例如实现IClonable
接口,创建Clone
方法(简单的实现不适用于嵌套的复杂对象,为此请检查这个问题:深度克隆对象(,使用AutoMapper
库。
下面是创建 Clone
方法的示例:
public class MyVal
{
public int id { get; set; }
public double SomeVal { get; set; }
public MyVal Clone(MyVal obj)
{
return new MyVal {id = obj.id, SomeVal = obj.SomeVal }
}
}