EF SaveChanges方法背后的逻辑是什么?

EF SaveChanges方法背后的逻辑是什么?

这是可行的,没有ref

代码语言:javascript运行复制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代码时,内存中会发生这样的情况:

代码语言:javascript运行复制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 dataref是一种机制,它允许SaveChanges将传递的面对面替换为一个完整的new人员。如果您有一个SaveChanges,如:

代码语言:javascript运行复制void SaveChanges(Person per){

per = new Person{ Name = "Jane", Id = 234 }

}然后,内存步骤中的对象将如下所示:

代码语言:javascript运行复制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:

代码语言:javascript运行复制void SaveChanges(ref Person per){

per = new ...

}ref的意思是p和per是相同的引用。没有一个额外的,它可以指向其他地方,而p停留在指向约翰

假设ref暂时将p重命名为per,因此执行per = new Person的SaveChanges方法也会影响p。可以这样想:

代码语言:javascript运行复制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核心保存更改时,它不会将您传入的实体批量替换为一个新实体;它会修改实体中的一些数据。您的代码不需要ref来查看它所做的更改

甚至,EF是一个两步进程--将实体传递到Add中,EF将其存储在内部列表中,当它通过自己的引用为它访问数据时,但是因为只有一个数据,并且变量和EF的列表都指向相同的数据,当EF更改变量所看到的数据时,因为它位于相同的内存位置。

相关推荐