Reputation: 5846
I have an EF Code First table that contains data I do not ever want to change, but I want to retrieve the data to a couple of variables that are independent of each other. The problem is that making a change to either variable changes the values of the other one.
For example, the EF Code First context is defined:
public class MyVal {
public int id { get; set; }
public double SomeVal { get; set; }
}
After populating the table with data:
context.MyVals.AddOrUpdate(new MyVal { SomeVal = 1 });
context.MyVals.AddOrUpdate(new MyVal { SomeVal = 2 });
context.MyVals.AddOrUpdate(new MyVal { SomeVal = 3 });
Next, I perform a query:
List<MyVal> myvals = _context.MyVals.AsNoTracking().Where(d => d.SomeVal >= 0).Select(m => m).ToList();
The above query returns the expected data. As you can see, I've specified AsNoTracking(). Next I want to create another var that I will modify:
List<MyVal> myvals1 = myvals;
And now I want to modify myvals1 WITHOUT effecting any values in myvals:
foreach (MyVal m in myvals1) {
m.SomeVal = m.SomeVal * 2;
}
myvals1 will now contain 3 records with these values:
2
4
6
The problem is that myvals also gets changed to:
2
4
6
Since I used AsNoTracking() when I queried the context, what else do I need to do to make these variables independent of each other? Why are these variables seemingly treated as the same?
Upvotes: 0
Views: 436
Reputation: 12324
The thing is that you are not creating a new object by simply assigning to a variable, as object int c# are passed by reference, not by a value. So when you are assigning myvals
to myvals1
you simply pass a reference to the same object. So you need to create a new List
and work with it:
List<MyVal> myvals1 = new List<MyVal>(myvals);
If you need to create an object of MyVal
from another object there are multiple solutions like implementing IClonable
interface, creating a Clone
method (the simple implementation won't work for nested complex objects, to do this check this question: Deep cloning objects), using an AutoMapper
library.
Here's an example of creating a Clone
method:
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 }
}
}
Upvotes: 1