{"id":243,"date":"2023-10-15T15:06:20","date_gmt":"2023-10-15T07:06:20","guid":{"rendered":"https:\/\/miie.net\/?p=243"},"modified":"2023-10-15T15:06:20","modified_gmt":"2023-10-15T07:06:20","slug":"ultimate-asp-net-core-web-api-chapter11-working-with-put-requests","status":"publish","type":"post","link":"https:\/\/diji.net\/?p=243","title":{"rendered":"Chapter11:WORKING WITH PUT REQUESTS"},"content":{"rendered":"<h1>11 WORKING WITH PUT REQUESTS<\/h1>\n<p>In this section, we are going to show you how to update a resource using the PUT request. We are going to update a child resource first and then we are going to show you how to execute insert while updating a parent resource.<br \/>\n\u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5c06\u5411\u60a8\u5c55\u793a\u5982\u4f55\u4f7f\u7528 PUT \u8bf7\u6c42\u66f4\u65b0\u8d44\u6e90\u3002\u6211\u4eec\u5c06\u9996\u5148\u66f4\u65b0\u5b50\u8d44\u6e90\uff0c\u7136\u540e\u5411\u60a8\u5c55\u793a\u5982\u4f55\u5728\u66f4\u65b0\u7236\u8d44\u6e90\u65f6\u6267\u884c\u63d2\u5165\u3002<\/p>\n<\/p>\n<h2>11.1 Updating Employee<\/h2>\n<p>In the previous sections, we first changed our interface, then the repository class, and finally the controller. But for the update, this doesn\u2019t have to be the case.<br \/>\n\u5728\u524d\u9762\u7684\u90e8\u5206\u4e2d\uff0c\u6211\u4eec\u9996\u5148\u66f4\u6539\u4e86\u63a5\u53e3\uff0c\u7136\u540e\u66f4\u6539\u4e86\u5b58\u50a8\u5e93\u7c7b\uff0c\u6700\u540e\u66f4\u6539\u4e86\u63a7\u5236\u5668\u3002\u4f46\u662f\u5bf9\u4e8e\u66f4\u65b0\uff0c\u60c5\u51b5\u4e0d\u4e00\u5b9a\u5982\u6b64\u3002<\/p>\n<p>Let\u2019s go step by step.<br \/>\n\u8ba9\u6211\u4eec\u4e00\u6b65\u4e00\u6b65\u6765\u3002<\/p>\n<p>The first thing we are going to do is to create another DTO class for update purposes:<br \/>\n\u6211\u4eec\u8981\u505a\u7684\u7b2c\u4e00\u4ef6\u4e8b\u662f\u521b\u5efa\u53e6\u4e00\u4e2a DTO \u7c7b\u4ee5\u8fdb\u884c\u66f4\u65b0\uff1a<\/p>\n<p><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/EmployeeForUpdateDto.cs\n\nnamespace Entities.DataTransferObjects\n{\n    public class EmployeeForUpdateDto\n    {\n        public string Name { get; set; }\n        public int Age { get; set; }\n        public string Position { get; set; }\n    }\n}\n\n<\/pre>\n<\/p>\n<p>We do not require the Id property because it will be accepted through the URI, like with the DELETE requests. Additionally, this DTO contains the same properties as the DTO for creation, but there is a conceptual difference between those two DTO classes. One is for updating and the other is for creating. Furthermore, once we get to the validation part, we will understand the additional difference between those two.<br \/>\n\u6211\u4eec\u4e0d\u9700\u8981 Id \u5c5e\u6027\uff0c\u56e0\u4e3a\u5b83\u5c06\u901a\u8fc7 URI \u63a5\u53d7\uff0c\u5c31\u50cf DELETE \u8bf7\u6c42\u4e00\u6837\u3002\u6b64\u5916\uff0c\u6b64 DTO \u5305\u542b\u4e0e\u7528\u4e8e\u521b\u5efa\u7684 DTO \u76f8\u540c\u7684\u5c5e\u6027\uff0c\u4f46\u8fd9\u4e24\u4e2a DTO \u7c7b\u4e4b\u95f4\u5b58\u5728\u6982\u5ff5\u5dee\u5f02\u3002\u4e00\u4e2a\u7528\u4e8e\u66f4\u65b0\uff0c\u53e6\u4e00\u4e2a\u7528\u4e8e\u521b\u5efa\u3002\u6b64\u5916\uff0c\u4e00\u65e6\u6211\u4eec\u8fdb\u5165\u9a8c\u8bc1\u90e8\u5206\uff0c\u6211\u4eec\u5c06\u4e86\u89e3\u8fd9\u4e24\u8005\u4e4b\u95f4\u7684\u5176\u4ed6\u533a\u522b\u3002<\/p>\n<p>Because we have additional DTO class, we require an additional mapping rule:<br \/>\n\u56e0\u4e3a\u6211\u4eec\u6709\u989d\u5916\u7684 DTO \u7c7b\uff0c\u6240\u4ee5\u6211\u4eec\u9700\u8981\u4e00\u4e2a\u989d\u5916\u7684\u6620\u5c04\u89c4\u5219\uff1a<\/p>\n<p><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/MappingProfile.cs\n\nCreateMap&lt;EmployeeForUpdateDto, Employee&gt;();\n<\/pre>\n<\/p>\n<p>Now, when we have all of these, let\u2019s modify the EmployeesController:<br \/>\n\u73b0\u5728\uff0c\u5f53\u6211\u4eec\u62e5\u6709\u6240\u6709\u8fd9\u4e9b\u65f6\uff0c\u8ba9\u6211\u4eec\u4fee\u6539\u5458\u5de5\u63a7\u5236\u5668\uff1a<\/p>\n<p><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/EmployeesController.cs\n\n    &#x5B;HttpPut(&quot;{id}&quot;)]\n    public IActionResult UpdateEmployeeForCompany(Guid companyId, Guid id, &#x5B;FromBody] EmployeeForUpdateDto employee)\n    {\n        if (employee == null)\n        {\n            _logger.LogError(&quot;EmployeeForUpdateDto object sent from client is null.&quot;);\n            return BadRequest(&quot;EmployeeForUpdateDto object is null&quot;);\n        }\n        var company = _repository.Company.GetCompany(companyId, trackChanges: false);\n        if (company == null)\n        {\n            _logger.LogInfo($&quot;Company with id: {companyId} doesn&#039;t exist in the database.&quot;);\n            return NotFound();\n        }\n        var employeeEntity = _repository.Employee.GetEmployee(companyId, id, trackChanges: true);\n        if (employeeEntity == null)\n        {\n            _logger.LogInfo($&quot;Employee with id: {id} doesn&#039;t exist in the database.&quot;);\n            return NotFound();\n        }\n        _mapper.Map(employee, employeeEntity);\n        _repository.Save();\n        return NoContent();\n    }\n<\/pre>\n<\/p>\n<p>We are using the PUT attribute with the id parameter to annotate this action. That means that our route for this action is going to be:<br \/>\napi\/companies\/{companyId}\/employees\/{id}.<\/p>\n<p>\u6211\u4eec\u5c06 PUT \u5c5e\u6027\u4e0e id \u53c2\u6570\u4e00\u8d77\u4f7f\u7528\u6765\u6ce8\u91ca\u6b64\u64cd\u4f5c\u3002\u8fd9\u610f\u5473\u7740\u6211\u4eec\u6267\u884c\u6b64\u64cd\u4f5c\u7684\u8def\u7531\u5c06\u662f\uff1a<br \/>\napi\/companies\/{companyId}\/employees\/{id}\u3002<\/p>\n<p>As you can see, we have three checks in our code and they are familiar to us. But we have one difference. Pay attention to the way we fetch the company and the way we fetch the employeeEntity. Do you see the difference?<br \/>\n\u5982\u60a8\u6240\u89c1\uff0c\u6211\u4eec\u7684\u4ee3\u7801\u4e2d\u6709\u4e09\u4e2a\u68c0\u67e5\uff0c\u6211\u4eec\u5f88\u719f\u6089\u5b83\u4eec\u3002\u4f46\u6211\u4eec\u6709\u4e00\u4e2a\u533a\u522b\u3002\u6ce8\u610f\u6211\u4eec\u83b7\u53d6\u516c\u53f8\u7684\u65b9\u5f0f\u4ee5\u53ca\u6211\u4eec\u83b7\u53d6\u5458\u5de5\u5b9e\u4f53\u7684\u65b9\u5f0f\u3002\u4f60\u770b\u51fa\u533a\u522b\u4e86\u5417\uff1f<\/p>\n<p>The trackChanges parameter is set to true for the employeeEntity. That\u2019s because we want EF Core to track changes on this entity. This means that as soon as we change any property in this entity, EF Core will set the state of that entity to Modified.<br \/>\n\u5bf9\u4e8e employeeEntity\uff0ctrackChanges \u53c2\u6570\u8bbe\u7f6e\u4e3a true\u3002\u8fd9\u662f\u56e0\u4e3a\u6211\u4eec\u5e0c\u671b EF Core \u8ddf\u8e2a\u6b64\u5b9e\u4f53\u4e0a\u7684\u66f4\u6539\u3002\u8fd9\u610f\u5473\u7740\uff0c\u53ea\u8981\u6211\u4eec\u66f4\u6539\u6b64\u5b9e\u4f53\u4e2d\u7684\u4efb\u4f55\u5c5e\u6027\uff0cEF Core \u5c31\u4f1a\u5c06\u8be5\u5b9e\u4f53\u7684\u72b6\u6001\u8bbe\u7f6e\u4e3a\u201c\u5df2\u4fee\u6539\u201d\u3002<\/p>\n<p>As you can see, we are mapping from the employee object (we will change just the age property in a request) to the employeeEntity \u2014 thus changing the state of the employeeEntity object to Modified.<br \/>\n\u5982\u60a8\u6240\u89c1\uff0c\u6211\u4eec\u6b63\u5728\u4ece employee \u5bf9\u8c61\uff08\u6211\u4eec\u5c06\u53ea\u66f4\u6539\u8bf7\u6c42\u4e2d\u7684 age \u5c5e\u6027\uff09\u6620\u5c04\u5230 employeeEntity\uff0c\u4ece\u800c\u5c06 employeeEntity \u5bf9\u8c61\u7684\u72b6\u6001\u66f4\u6539\u4e3a Modified\u3002<\/p>\n<p>Because our entity has a modified state, it is enough to call the Save method without any additional update actions. As soon as we call the Save method, our entity is going to be updated in the database.<br \/>\n\u7531\u4e8e\u6211\u4eec\u7684\u5b9e\u4f53\u5177\u6709\u4fee\u6539\u72b6\u6001\uff0c\u56e0\u6b64\u65e0\u9700\u4efb\u4f55\u5176\u4ed6\u66f4\u65b0\u64cd\u4f5c\u5373\u53ef\u8c03\u7528 Save \u65b9\u6cd5\u3002\u4e00\u65e6\u6211\u4eec\u8c03\u7528 Save \u65b9\u6cd5\uff0c\u6211\u4eec\u7684\u5b9e\u4f53\u5c31\u4f1a\u5728\u6570\u636e\u5e93\u4e2d\u66f4\u65b0\u3002<\/p>\n<p>Finally, we return the 204 NoContent status.<br \/>\n\u6700\u540e\uff0c\u6211\u4eec\u8fd4\u56de 204 NoContent \u72b6\u6001\u3002<\/p>\n<p>We can test our action:<br \/>\n\u6211\u4eec\u53ef\u4ee5\u6d4b\u8bd5\u6211\u4eec\u7684\u64cd\u4f5c\uff1a<\/p>\n<p><pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{\n    &quot;name&quot;:&quot;Sam Raiden&quot;,\n    &quot;age&quot;:25,\n    &quot;position&quot;:&quot;Software developer&quot;\n}\n<\/pre>\n<\/p>\n<p><a href=\"https:\/\/localhost:5001\/api\/companies\/C9D4C053-49B6-410C-BC78-2D54A9991870\/employees\/80ABBCA8-664D-4B20-B5DE-024705497D4A\"><a href=\"https:\/\/localhost:5001\/api\/companies\/C9D4C053-49B6-410C-BC78-2D54A9991870\/employees\/80ABBCA8-664D-4B20-B5DE-024705497D4A\"><a href=\"https:\/\/localhost:5001\/api\/companies\/C9D4C053-49B6-410C-BC78-2D54A9991870\/employees\/80ABBCA8-664D-4B20-B5DE-024705497D4A\">https:\/\/localhost:5001\/api\/companies\/C9D4C053-49B6-410C-BC78-2D54A9991870\/employees\/80ABBCA8-664D-4B20-B5DE-024705497D4A<\/a><\/a><\/a><\/p>\n<p><img decoding=\"async\" src=\"\/img\/20220824-ultimate-asp-net-core-web-api\/Image_1101.jpg\" alt=\"Alt text\" \/><\/p>\n<p>And it works; we get the 204 No Content status.<br \/>\n\u5b83\u6709\u6548;\u6211\u4eec\u5f97\u5230 204 \u65e0\u5185\u5bb9\u72b6\u6001\u3002<\/p>\n<p>We can check our executed query through EF Core to confirm that only the Age column is updated:<br \/>\n\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7 EF Core \u68c0\u67e5\u5df2\u6267\u884c\u7684\u67e5\u8be2\uff0c\u4ee5\u786e\u8ba4\u4ec5\u66f4\u65b0\u4e86\u201c\u5e74\u9f84\u201d\u5217\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/img\/20220824-ultimate-asp-net-core-web-api\/Image_1102.gif\" alt=\"Alt text\" \/><\/p>\n<p>Excellent.<br \/>\n\u975e\u5e38\u597d\u3002<\/p>\n<p>You can send the same request with the invalid company id or employee id. In both cases, you should get a 404 response, which is a valid response to this kind of situation.<br \/>\n\u60a8\u53ef\u4ee5\u4f7f\u7528\u65e0\u6548\u7684\u516c\u53f8 ID \u6216\u5458\u5de5 ID \u53d1\u9001\u76f8\u540c\u7684\u8bf7\u6c42\u3002\u5728\u8fd9\u4e24\u79cd\u60c5\u51b5\u4e0b\uff0c\u60a8\u90fd\u5e94\u8be5\u5f97\u5230 404 \u54cd\u5e94\uff0c\u8fd9\u662f\u5bf9\u8fd9\u79cd\u60c5\u51b5\u7684\u6709\u6548\u54cd\u5e94\u3002<\/p>\n<p><strong>Additional<\/strong> note: As you can see, we have changed only the <strong>Age<\/strong> property, but we have sent all the other properties with unchanged values as well. Therefore, <strong>Age<\/strong> is only updated in the database. But if we send the object with just the <strong>Age<\/strong> property, without the other properties, those other properties will be set to their default values and the whole object will be updated \u2014 not just the <strong>Age<\/strong> column. That\u2019s because the PUT is a request for a full update. This is very important to know.<br \/>\n<strong>\u9644\u52a0\u8bf4\u660e<\/strong>\uff1a \u5982\u60a8\u6240\u89c1\uff0c\u6211\u4eec\u53ea\u66f4\u6539\u4e86 Age \u5c5e\u6027\uff0c\u4f46\u6211\u4eec\u4e5f\u53d1\u9001\u4e86\u5177\u6709\u672a\u66f4\u6539\u503c\u7684\u6240\u6709\u5176\u4ed6\u5c5e\u6027\u3002\u56e0\u6b64\uff0c\u5e74\u9f84\u4ec5\u5728\u6570\u636e\u5e93\u4e2d\u66f4\u65b0\u3002\u4f46\u662f\uff0c\u5982\u679c\u6211\u4eec\u53d1\u9001\u7684\u5bf9\u8c61\u53ea\u5305\u542b Age \u5c5e\u6027\uff0c\u800c\u4e0d\u53d1\u9001\u5176\u4ed6\u5c5e\u6027\uff0c\u5219\u8fd9\u4e9b\u5176\u4ed6\u5c5e\u6027\u5c06\u8bbe\u7f6e\u4e3a\u5176\u9ed8\u8ba4\u503c\uff0c\u5e76\u4e14\u6574\u4e2a\u5bf9\u8c61\u5c06\u88ab\u66f4\u65b0 \u2014 \u800c\u4e0d\u4ec5\u4ec5\u662f Age \u5217\u3002\u8fd9\u662f\u56e0\u4e3a PUT \u662f\u5bf9\u5b8c\u6574\u66f4\u65b0\u7684\u8bf7\u6c42\u3002\u4e86\u89e3\u8fd9\u4e00\u70b9\u975e\u5e38\u91cd\u8981\u3002<\/p>\n<h3>11.1.1 About the Update Method from the RepositoryBase Class<\/h3>\n<p>Right now, you might be asking: \u201cWhy do we have the Update method in the RepositoryBase class if we are not using it?\u201d<br \/>\n\u73b0\u5728\uff0c\u60a8\u53ef\u80fd\u4f1a\u95ee\uff1a\u201c\u5982\u679c\u6211\u4eec\u4e0d\u4f7f\u7528 RepositoryBase \u7c7b\u4e2d\u7684 Update \u65b9\u6cd5\uff0c\u4e3a\u4ec0\u4e48\u4f1a\u6709\u5b83\uff1f<\/p>\n<p>The update action we just executed is a connected update (an update where we use the same context object to fetch the entity and to update it). But sometimes we can work with disconnected updates. This kind of update action uses different context objects to execute fetch and update actions or sometimes we can receive an object from a client with the Id property set as well, so we don\u2019t have to fetch it from the database. In that situation, all we have to do is to inform EF Core to track changes on that entity and to set its state to modified. We can do both actions with the Update method from our RepositoryBase class. So, you see, having that method is crucial as well.<br \/>\n\u6211\u4eec\u521a\u521a\u6267\u884c\u7684\u66f4\u65b0\u64cd\u4f5c\u662f\u8fde\u63a5\u66f4\u65b0\uff08\u6211\u4eec\u4f7f\u7528\u76f8\u540c\u7684\u4e0a\u4e0b\u6587\u5bf9\u8c61\u6765\u83b7\u53d6\u5b9e\u4f53\u5e76\u5bf9\u5176\u8fdb\u884c\u66f4\u65b0\u7684\u66f4\u65b0\uff09\u3002\u4f46\u6709\u65f6\u6211\u4eec\u53ef\u4ee5\u5904\u7406\u65ad\u5f00\u8fde\u63a5\u7684\u66f4\u65b0\u3002\u8fd9\u79cd\u66f4\u65b0\u64cd\u4f5c\u4f7f\u7528\u4e0d\u540c\u7684\u4e0a\u4e0b\u6587\u5bf9\u8c61\u6765\u6267\u884c\u83b7\u53d6\u548c\u66f4\u65b0\u64cd\u4f5c\uff0c\u6216\u8005\u6709\u65f6\u6211\u4eec\u4e5f\u53ef\u4ee5\u4ece\u8bbe\u7f6e\u4e86 Id \u5c5e\u6027\u7684\u5ba2\u6237\u7aef\u63a5\u6536\u5bf9\u8c61\uff0c\u56e0\u6b64\u6211\u4eec\u4e0d\u5fc5\u4ece\u6570\u636e\u5e93\u4e2d\u83b7\u53d6\u5b83\u3002\u5728\u8fd9\u79cd\u60c5\u51b5\u4e0b\uff0c\u6211\u4eec\u8981\u505a\u7684\u5c31\u662f\u901a\u77e5 EF Core \u8ddf\u8e2a\u8be5\u5b9e\u4f53\u4e0a\u7684\u66f4\u6539\uff0c\u5e76\u5c06\u5176\u72b6\u6001\u8bbe\u7f6e\u4e3a\u5df2\u4fee\u6539\u3002\u6211\u4eec\u53ef\u4ee5\u4f7f\u7528 RepositoryBase \u7c7b\u4e2d\u7684 Update \u65b9\u6cd5\u6267\u884c\u8fd9\u4e24\u4e2a\u64cd\u4f5c\u3002\u6240\u4ee5\uff0c\u4f60\u770b\uff0c\u62e5\u6709\u8fd9\u79cd\u65b9\u6cd5\u4e5f\u662f\u81f3\u5173\u91cd\u8981\u7684\u3002<\/p>\n<p>One note, though. If we use the Update method from our repository, even if we change just the Age property, all properties will be updated in the database.<br \/>\n\u4e0d\u8fc7\uff0c\u6709\u4e00\u70b9\u9700\u8981\u6ce8\u610f\u3002\u5982\u679c\u6211\u4eec\u4f7f\u7528\u5b58\u50a8\u5e93\u4e2d\u7684 Update \u65b9\u6cd5\uff0c\u5373\u4f7f\u6211\u4eec\u53ea\u66f4\u6539 Age \u5c5e\u6027\uff0c\u6570\u636e\u5e93\u4e2d\u7684\u6240\u6709\u5c5e\u6027\u90fd\u5c06\u66f4\u65b0\u3002<\/p>\n<h2>11.2 Inserting Resources while Updating one<\/h2>\n<p>While updating a parent resource, we can create child resources as well without too much effort. EF Core helps us a lot with that process. Let\u2019s see how.<br \/>\n\u5728\u66f4\u65b0\u7236\u8d44\u6e90\u65f6\uff0c\u6211\u4eec\u4e5f\u53ef\u4ee5\u6beb\u4e0d\u8d39\u529b\u5730\u521b\u5efa\u5b50\u8d44\u6e90\u3002EF Core \u5728\u6b64\u8fc7\u7a0b\u65b9\u9762\u4e3a\u6211\u4eec\u63d0\u4f9b\u4e86\u5f88\u591a\u5e2e\u52a9\u3002\u8ba9\u6211\u4eec\u770b\u770b\u5982\u4f55\u3002<\/p>\n<p>The first thing we are going to do is to create a DTO class for update:<br \/>\n\u6211\u4eec\u8981\u505a\u7684\u7b2c\u4e00\u4ef6\u4e8b\u662f\u521b\u5efa\u4e00\u4e2a\u7528\u4e8e\u66f4\u65b0\u7684 DTO \u7c7b\uff1a<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/CompanyForUpdateDto.cs\n\nusing System.Collections.Generic;\n\nnamespace Entities.DataTransferObjects\n{\n    public class CompanyForUpdateDto\n    {\n        public string Name { get; set; }\n        public string Address { get; set; }\n        public string Country { get; set; }\n        public IEnumerable&lt;EmployeeForCreationDto&gt; Employees { get; set; }\n    }\n}\n\n<\/pre>\n<\/p>\n<p>After this, let\u2019s create a new mapping rule:<br \/>\n\u5728\u6b64\u4e4b\u540e\uff0c\u8ba9\u6211\u4eec\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u6620\u5c04\u89c4\u5219\uff1a<\/p>\n<p><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/MappingProfile.cs\nCreateMap&lt;CompanyForUpdateDto, Company&gt;();\n<\/pre>\n<\/p>\n<p>Right now, we can modify our controller:<br \/>\n\u73b0\u5728\uff0c\u6211\u4eec\u53ef\u4ee5\u4fee\u6539\u6211\u4eec\u7684\u63a7\u5236\u5668\uff1a<\/p>\n<p><pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\n\/\/CompaniesController.cs\n        &#x5B;HttpPut(&quot;{id}&quot;)]\n        public IActionResult UpdateCompany(Guid id, &#x5B;FromBody] CompanyForUpdateDto company)\n        {\n            if (company == null)\n            {\n                _logger.LogError(&quot;CompanyForUpdateDto object sent from client is null.&quot;);\n                return BadRequest(&quot;CompanyForUpdateDto object is null&quot;);\n            }\n            var companyEntity = _repository.Company.GetCompany(id, trackChanges: true);\n            if (companyEntity == null)\n            {\n                _logger.LogInfo($&quot;Company with id: {id} doesn&#039;t exist in the database.&quot;);\n                return NotFound();\n            }\n            _mapper.Map(company, companyEntity);\n            _repository.Save(); return NoContent();\n        }\n<\/pre>\n<\/p>\n<p>That\u2019s it. You can see that this action is almost the same as the employee update action.<br \/>\n\u5c31\u662f\u8fd9\u6837\u3002\u60a8\u53ef\u4ee5\u770b\u5230\u6b64\u64cd\u4f5c\u4e0e\u5458\u5de5\u66f4\u65b0\u64cd\u4f5c\u51e0\u4e4e\u76f8\u540c\u3002<\/p>\n<p>Let\u2019s test this now:<br \/>\n\u73b0\u5728\u8ba9\u6211\u4eec\u6d4b\u8bd5\u4e00\u4e0b\uff1a<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\n{\n    &quot;name&quot;:&quot;Admin_Solutions Ltd Upd&quot;,\n    &quot;address&quot;:&quot;312 Forest Avenue,BF 923&quot;,\n    &quot;country&quot;:&quot;USA&quot;,\n    &quot;employees&quot;:&#x5B;\n        {\n            &quot;name&quot;:&quot;Geil Metain&quot;,\n            &quot;age&quot;:23,\n            &quot;position&quot;:&quot;Admin&quot;\n        }\n    ]\n}\n<\/pre>\n<\/p>\n<p><a href=\"https:\/\/localhost:5001\/api\/companies\/3d490a70-94ce-4d15-9494-5248280c2ce3\"><a href=\"https:\/\/localhost:5001\/api\/companies\/3d490a70-94ce-4d15-9494-5248280c2ce3\"><a href=\"https:\/\/localhost:5001\/api\/companies\/3d490a70-94ce-4d15-9494-5248280c2ce3\">https:\/\/localhost:5001\/api\/companies\/3d490a70-94ce-4d15-9494-5248280c2ce3<\/a><\/a><\/a><\/p>\n<p><img decoding=\"async\" src=\"\/img\/20220824-ultimate-asp-net-core-web-api\/Image_1103.jpg\" alt=\"Alt text\" \/><\/p>\n<p>We modify the name of the company and attach an employee as well. As a result, we can see <strong>204<\/strong>, which means that the entity has been updated. But what about that new employee?<br \/>\n\u6211\u4eec\u4fee\u6539\u516c\u53f8\u540d\u79f0\u5e76\u9644\u52a0\u5458\u5de5\u3002\u7ed3\u679c\uff0c\u6211\u4eec\u53ef\u4ee5\u770b\u5230 204\uff0c\u8fd9\u610f\u5473\u7740\u5b9e\u4f53\u5df2\u66f4\u65b0\u3002\u4f46\u662f\u90a3\u4e2a\u65b0\u5458\u5de5\u5462\uff1f<\/p>\n<p>Let\u2019s inspect our query:<br \/>\n\u8ba9\u6211\u4eec\u68c0\u67e5\u4e00\u4e0b\u6211\u4eec\u7684\u67e5\u8be2\uff1a<\/p>\n<p><img decoding=\"async\" src=\"\/img\/20220824-ultimate-asp-net-core-web-api\/Image_1104.jpg\" alt=\"Alt text\" \/><\/p>\n<p>You can see that we have created the <strong>employee<\/strong> entity in the database. So, EF Core does that job for us because we track the <strong>company<\/strong> entity. As soon as mapping occurs, EF Core sets the state for the <strong>company<\/strong> entity to <strong>modified<\/strong> and for all the employees to <strong>added<\/strong>. After we call the <strong>Save<\/strong> method, the <strong>Name<\/strong> property is going to be modified and the <strong>employee<\/strong> entity is going to be created in the database.<br \/>\n\u60a8\u53ef\u4ee5\u770b\u5230\u6211\u4eec\u5df2\u7ecf\u5728\u6570\u636e\u5e93\u4e2d\u521b\u5efa\u4e86\u5458\u5de5\u5b9e\u4f53\u3002\u56e0\u6b64\uff0cEF Core \u4e3a\u6211\u4eec\u5b8c\u6210\u4e86\u8fd9\u9879\u5de5\u4f5c\uff0c\u56e0\u4e3a\u6211\u4eec\u8ddf\u8e2a\u516c\u53f8\u5b9e\u4f53\u3002\u53d1\u751f\u6620\u5c04\u540e\uff0cEF Core \u5c06\u8bbe\u7f6e\u8981\u4fee\u6539\u7684\u516c\u53f8\u5b9e\u4f53\u548c\u8981\u6dfb\u52a0\u7684\u6240\u6709\u5458\u5de5\u7684\u72b6\u6001\u3002\u8c03\u7528 Save \u65b9\u6cd5\u540e\uff0c\u5c06\u4fee\u6539 Name \u5c5e\u6027\uff0c\u5e76\u5728\u6570\u636e\u5e93\u4e2d\u521b\u5efa\u96c7\u5458\u5b9e\u4f53\u3002<\/p>\n<p>We are finished with the PUT requests, so let\u2019s continue with PATCH.<br \/>\n\u6211\u4eec\u5df2\u7ecf\u5b8c\u6210\u4e86 PUT \u8bf7\u6c42\uff0c\u6240\u4ee5\u8ba9\u6211\u4eec\u7ee7\u7eed\u4f7f\u7528 PATCH\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>11 WORKING WITH PUT REQUESTS In this section, we are going to show you how to update a resource using the PUT request. We are going to update a child resource first and then we are going to show you how to execute insert while updating a parent resource. \u5728\u672c\u8282\u4e2d\uff0c\u6211\u4eec\u5c06\u5411\u60a8\u5c55\u793a\u5982\u4f55\u4f7f\u7528 PUT \u8bf7\u6c42\u66f4\u65b0\u8d44\u6e90\u3002\u6211\u4eec\u5c06\u9996\u5148\u66f4\u65b0\u5b50\u8d44\u6e90\uff0c\u7136\u540e\u5411\u60a8\u5c55\u793a\u5982\u4f55\u5728\u66f4\u65b0\u7236\u8d44\u6e90\u65f6\u6267\u884c\u63d2\u5165\u3002 11.1 Updating Employee [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[23],"class_list":["post-243","post","type-post","status-publish","format-standard","hentry","category-csharp","tag-ultimate-asp-net-core-web-api"],"_links":{"self":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/243","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=243"}],"version-history":[{"count":0,"href":"https:\/\/diji.net\/index.php?rest_route=\/wp\/v2\/posts\/243\/revisions"}],"wp:attachment":[{"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=243"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=243"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/diji.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=243"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}