EF SaveChanges 方法背后的逻辑是什么?
What is the logic behind EF SaveChanges Method?
当我在 DBSet 中插入一个新项目时,例如:
var newItemAdded = MyDBSet.Add(itemToAdd);
然后我将更改保存在数据库中,如:
MyContext.SaveChanges();
我的变量 newItemAdded 已使用数据库自动生成的新 ID 更新。
我去EF Core Github看了逻辑,但是仓库里的文件很多,我不确定背后的逻辑。
我更关心的是插入后执行的 SaveChanges 如何更新 newItemAdded。 EF 似乎没有使用 ref.
也许有人已经知道它是如何工作的?
谢谢
这有效,没有 ref
:
class Person{
int Id {get;set;} = -1;
string Name {get;set;}
}
...
void SaveChanges(Person per){ //no ref here
//simulate saving to DB
per.Id = new Random().Next();
}
...
var p = new Person{ Name = "John"; }
Console.WriteLine(p.Id); //prints -1;
SaveChanges(p);
Console.WriteLine(p.Id); //prints some random number
我们从来不需要 ref
来确保在 SaveChanges 中设置的人的 ID 仍然存在,并且在 SaveChanges 完成后被 p
看到。
从概念上讲,这是调用上面的 SaveChanges 代码时内存中发生的情况:
p --> [ John, -1 ] //var p = new Person{Name = "John"}
p --> [ John, -1 ] <-- per //SaveChanges(p), establishes another variable per, pointing at the same in memory data
p --> [ John, 23 ] <-- per //per.Id = random number
p --> [ John, 23 ] //method exits, variable per goes away. p survives and sees changed data
ref
是一种允许 SaveChanges 将传入的 Person 换出整个 new
Person 的机制。如果你有一个像这样的 SaveChanges:
void SaveChanges(Person per){
per = new Person{ Name = "Jane", Id = 234 }
}
然后内存步骤中的对象将如下所示:
p --> [ John, -1 ] //var p = new Person{Name = "John"}
p --> [ John, -1 ] <-- per //SaveChanges(p), establishes another reference called per, pointing at the same in-memory data
p --> [ John, -1 ] per --> [Sarah, 23] //per is reassigned to a new Person created elsewhere in memory
p --> [ John, -1 ] //method exits, variable per goes away. Sarah is vaporized. John was never changed
假设我们使用 ref:
void SaveChanges(ref Person per){
per = new ...
}
ref
表示 p
和 per
是同一个引用。没有另外制作一个,可以指向其他地方,而 p
一直指向 John
假设 ref
暂时将 p
重命名为 per
,因此执行 per = new Person
的 SaveChanges 方法也会影响 p
。它可以被认为是这样的:
p ---------> [ John, -1 ] //var p = new Person{Name = "John"}
per was p -> [ John, -1 ] //SaveChanges(p), establishes another variable per, pointing at the same in memory data
per was p -> [ Sarah, 23] //per = new Person..., John is lost here
p ---------> [ Sarah, 23] //method exits, variable per goes away. p is the only remaining reference,
当 EF core 保存更改时,它不会将您传入的实体全部替换为新实体;它修改了实体内部的一些数据。您的代码不需要 ref
就能看到它所做的更改
EF 是一个两步过程甚至无关紧要 - 您将实体传递给 Add,EF 将其存储在内部列表中,当它 SaveChanges() 时,它通过自己的引用访问数据,但是因为只有一个数据并且您的变量和 EF 的列表都指向相同的数据,所以当 EF 更改数据时您的变量会看到它,因为它是相同内存位置的相同数据
当我在 DBSet 中插入一个新项目时,例如:
var newItemAdded = MyDBSet.Add(itemToAdd);
然后我将更改保存在数据库中,如:
MyContext.SaveChanges();
我的变量 newItemAdded 已使用数据库自动生成的新 ID 更新。
我去EF Core Github看了逻辑,但是仓库里的文件很多,我不确定背后的逻辑。
我更关心的是插入后执行的 SaveChanges 如何更新 newItemAdded。 EF 似乎没有使用 ref.
也许有人已经知道它是如何工作的?
谢谢
这有效,没有 ref
:
class Person{
int Id {get;set;} = -1;
string Name {get;set;}
}
...
void SaveChanges(Person per){ //no ref here
//simulate saving to DB
per.Id = new Random().Next();
}
...
var p = new Person{ Name = "John"; }
Console.WriteLine(p.Id); //prints -1;
SaveChanges(p);
Console.WriteLine(p.Id); //prints some random number
我们从来不需要 ref
来确保在 SaveChanges 中设置的人的 ID 仍然存在,并且在 SaveChanges 完成后被 p
看到。
从概念上讲,这是调用上面的 SaveChanges 代码时内存中发生的情况:
p --> [ John, -1 ] //var p = new Person{Name = "John"}
p --> [ John, -1 ] <-- per //SaveChanges(p), establishes another variable per, pointing at the same in memory data
p --> [ John, 23 ] <-- per //per.Id = random number
p --> [ John, 23 ] //method exits, variable per goes away. p survives and sees changed data
ref
是一种允许 SaveChanges 将传入的 Person 换出整个 new
Person 的机制。如果你有一个像这样的 SaveChanges:
void SaveChanges(Person per){
per = new Person{ Name = "Jane", Id = 234 }
}
然后内存步骤中的对象将如下所示:
p --> [ John, -1 ] //var p = new Person{Name = "John"}
p --> [ John, -1 ] <-- per //SaveChanges(p), establishes another reference called per, pointing at the same in-memory data
p --> [ John, -1 ] per --> [Sarah, 23] //per is reassigned to a new Person created elsewhere in memory
p --> [ John, -1 ] //method exits, variable per goes away. Sarah is vaporized. John was never changed
假设我们使用 ref:
void SaveChanges(ref Person per){
per = new ...
}
ref
表示 p
和 per
是同一个引用。没有另外制作一个,可以指向其他地方,而 p
一直指向 John
假设 ref
暂时将 p
重命名为 per
,因此执行 per = new Person
的 SaveChanges 方法也会影响 p
。它可以被认为是这样的:
p ---------> [ John, -1 ] //var p = new Person{Name = "John"}
per was p -> [ John, -1 ] //SaveChanges(p), establishes another variable per, pointing at the same in memory data
per was p -> [ Sarah, 23] //per = new Person..., John is lost here
p ---------> [ Sarah, 23] //method exits, variable per goes away. p is the only remaining reference,
当 EF core 保存更改时,它不会将您传入的实体全部替换为新实体;它修改了实体内部的一些数据。您的代码不需要 ref
就能看到它所做的更改
EF 是一个两步过程甚至无关紧要 - 您将实体传递给 Add,EF 将其存储在内部列表中,当它 SaveChanges() 时,它通过自己的引用访问数据,但是因为只有一个数据并且您的变量和 EF 的列表都指向相同的数据,所以当 EF 更改数据时您的变量会看到它,因为它是相同内存位置的相同数据