首页 > 解决方案 > EF FirstOrDefault 创建对变量的引用

问题描述

所以我是 C# 及其所有生态系统的新手。我现在正在关注一个正在更新记录的教程:

    [HttpPut("{id}")]
    public async Task<IActionResult> UpdateSetup(int id, SetupForUpdateDto setupForUpdateDto)
    {
        var statusFromRepo = await this.setupRepository.GetValue(id);

        statusFromRepo.Name = setupForUpdateDto.Name;

        if (await this.setupRepository.saveAll())
        {
            return NoContent();
        }

        throw new Exception($"Updating User with Id: {id} failed on save");
    }

我不明白为什么如果变量保存到数据库的数据

statusFromRepo.Name = setupForUpdateDto.Name;

被更新然后

await this.setupRepository.saveAll()

是否有某种参考btwstatusFromRepo变量和setupRepository

标签: c#asp.netentity-framework

解决方案


这在一定程度上取决于 setupRepository 的作用。很多时候,存储库(或存储库使用的 DbContext)会记住它获取的原始数据以及副本。这使得可以在不保存中间结果的情况下进行更改。

让我们从存储库中更改/添加/删除客户,看看会发生什么。

更改现有客户:

var customer = repository.FetchCustomerWithId(10);
// the original unchanged customer object is in the repository
// a copy of this object is also in the repository
// the copy equals the original
// I have a reference to this copy.

customer.Address = textBoxAddress.Text;
// the repository still has the original unchanged object
// my reference changed the copy object
// the copy is not equal to the original anymore.

添加新客户

Customer customerToAdd = new Customer() {...};
repository.AddCustomer(customerToAdd);
// I have a new customer object
// the repository has a reference to this object
// the repository has no original: so it knows it is added
// alternative: the respository remembers that is was added.

删除现有客户

Customer customerToDelete = repository.FetchCustomerWithId(20);
// repository has original fetched object
// repository has copy equal to original object
// I have reference to the copy.

 repository.DeleteCustomer(customerToDelete);
 // I still have reference to the customer, I can change it if I want
 // the repository still has the original fetched customer object
 // the repository has deleted its copied Customer object
 // alternative: repository has remembered that this object is deleted.

 customerToDelete.Address = ...
 // The repository has deleted the copy, but I had still a reference,
 // so the copied Customer still exists, but the Repository does not know 
 // about the changed address.

现在如果你调用 SaveAll 会发生什么:

repository.SaveAll();

存储库检查添加了哪些项目: 查找具有 NULL original 的副本对象:将对象添加到数据库

存储库检查哪些项目被删除:查找具有空副本对象的提取对象:从数据库中删除对象

存储库检查每个提取的具有非空副本的对象的所有属性:更新更改的属性。

替代方案:对于每个对象,存储库都会记住它是否被添加/删除/获取。仅对于获取的数据,它必须检查哪些属性需要更新。

如果存储库使用实体框架,那么DbContext.ChangeTracker检测更改的对象是:添加/删除/更改了哪些对象。

请参阅DbChangeTracker 类


推荐阅读