从表中删除一行并将布尔标志传递给 API,而不删除实际对象

Posted

技术标签:

【中文标题】从表中删除一行并将布尔标志传递给 API,而不删除实际对象【英文标题】:Deleting a row from a table and passing a Boolean flag to API, without deleting the actual object 【发布时间】:2019-06-29 20:52:47 【问题描述】:

我正在用 AngularJS 做一个 spa 并在 C# 中使用 mvvm 的一个 api。

我可以在单击删除按钮后删除一行,但在服务器上我只想通过将数据保存在 Sql Server 中来将布尔标志更改为 true。

我尝试了其他方法,我什至通过 Postman 删除了对象,但我不想删除,只是将布尔属性更改为我的视图表中不再存在的记录。

我会留下我的代码,以便更好地理解。

欢迎任何帮助。

我尝试在api控制器中传递id和对象,类似于http.put,因为我想更改一个布尔属性,所以我想保留id,name,last name,email和isdelete之后单击,删除视图中的行的更改在数据库中变为true。

 <tbody>
                <tr ng-repeat="register in registers">
                    <td style="display:none">register.UserId</td>
                    <td>register.Name</td>
                    <td>register.LastName</td>
                    <td><input type="checkbox" ng-model="register.IsActive" disabled /></td>
                    <td>register.Email</td>
                    <td>
                        <a ng-click="editRegister($event, register)" class="glyphicon glyphicon-edit"></a>
                    </td>
                    <td>
                        <a href="" ng-click="deleteRegister()" class="glyphicon glyphicon-trash"></a>
                    </td>
                </tr>
            </tbody>

我的控制器.js:

 $scope.deleteRegister = function (register) 
    var index = -1;
    var listOfRegister = eval($scope.registers);
    for (var i = 0; i < listOfRegister.length; i++) 
        if (listOfRegister[i].register === register) 
            index = i;
            break;
        
    
    if (index === -1) 
        alert("Something gone wrong");
    
    $scope.registers.splice(index, 1);
    $http(
        method: 'Delete',
        url: 'http://localhost:51734/api/UserAPI/',

    ).then(function (res) 
        alert('Exc');
        $scope.GetAllRegisters();
    )
;

还有我的controller.api:

[HttpPut]
    [Route("api/UserAPI")]
    public HttpResponseMessage Delete(UserViewModel uservm)
    
        try
                                        
            var registerDeleted = ctx.User.Find(uservm.UserId);
            uservm.IsDelete = false;
            uservm.IsActive = true;
            if (registerDeleted != null)
            
                uservm.IsActive = false;
                uservm.IsDelete = true;
                registerDeleted.Name = uservm.Name;
                registerDeleted.LastName = uservm.LastName;
                registerDeleted.IsActive = uservm.IsActive;
                registerDeleted.Email = uservm.Email;
                registerDeleted.IsDelete = uservm.IsDelete;
                ctx.Entry(registerDeleted).State = System.Data.Entity.EntityState.Modified;

                ctx.SaveChanges();
                return Request.CreateResponse(HttpStatusCode.OK);
            
            else
            
                return Request.CreateErrorResponse(HttpStatusCode.BadRequest, "User not found");
            
        
        catch (Exception ex)
        

            return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
        

    

谢谢!

【问题讨论】:

所以你有一个表,当你点击删除图标时,你希望删除行,对吗? db / api 端也在工作吗?而这只是更新当前模板的 UI 问题。 好的,当我单击删除图标时,我可以删除该行,就像您告诉我的那样,它减少了代码,使其更简洁。现在我想将对象的属性更改为 true。删除视图记录,但将其保存在 db / 中,状态 isDelete 为 true。具有相同的 id、name、lastName、isActive = false、Email 和 isDelete = true。我不想从 db / 中永久删除对象数据.我想保留记录,但在从视图中删除对象时,该属性使用从 isDelete 到 true 的标志。 ive 已为您更新了答案,但正如 Andrei Dragotoniu 所说,您可以只传入 userId 而不是整个 UserViewModel,这再次会使您的代码更整洁,更易于管理。 【参考方案1】:

您所说的是软删除数据行。 在数据库中添加一个名为 Status 或 IsDeleted 或任何您喜欢的新布尔字段,默认值为 false。 当您点击 UI 上的 Delete 按钮时,发出一个请求,将该标志从 false 简单地更新为 true

当您请求要在 UI 上显示的内容列表时,仅返回标志设置为 false 的内容。

这基本上是软删除数据背后的全部想法。您只是将数据标记为已删除,实际上并没有删除它。

如果您愿意,稍后您可以添加一个流程,将软删除的数据移动到存档表中,以保持事情整洁。以这种方式做事还有一个额外的好处,即您可以在需要时随时取消删除数据。您真正需要的只是将标志改回 false 就完成了,一切正常并显示数据。

最后一点,如果您只想软删除一个项目,那么您只需要传递记录的 id。您无需担心其他字段的更改。您通常不会同时更新信息并删除它。因此,创建一个响应 PUT 的简单控制器,例如:

[HttpPut]
    [Route("api/UserAPI")]
    public HttpResponseMessage Delete(int userId)
                                           
         var foundUser = ctx.User.Find(userId);
         foundUser.IsDeleted = true;
         ctx.SaveChanges();
    

当然,添加您的所有验证、返回代码以及您需要的一切,但这基本上就是您所需要的。

不要忘记更改返回活跃用户的方法,忽略那些 IsDeleted 标志为真的用户。

【讨论】:

这正是我想要做的,但我无法在 $scope.deleteRegister 方法中获取我的 controller.js 来调用我的 controller.api 中的 PUT。我按照你告诉我的那样更改了代码,它给出了以下错误:ReferenceError: userId is not defined at ChildScope。 $ scope.deleteRegister (registerController.js: 38)。我会留下我的代码作为一个新问题,以便您可以帮助我,如果可能的话,谢谢!【参考方案2】:

如果 API 是您设置 uservm.IsDelete = false; 的问题,则设置 registerDeleted.IsDelete = uservm.IsDelete; 因此它在数据库中始终为 false

如果模板是问题,我建议从data-ng-repeat 获取index,这将减少您编写的代码量并更容易查看发生了什么。

这将从表格中删除该行:

<tr data-ng-repeat="(index, register) in registers">    
     <td>
       <a href="data-ng-click="deleteRegister()" class="glyphicon glyphicon-trash"></a>
    </td>
</tr>      

$scope.deleteRegister = function (index) 
   $scope.registers.splice(index, 1);

评论更新:

您需要检索对象,然后进行更改并保存。

var registerDeleted = ctx.User.Find(uservm.UserId);
if (registerDeleted != null)

    registerDeleted.IsDelete = true;
    registerDeleted.IsActive = false
    ctx.SaveChanges();

【讨论】:

问题是它从我的 view.cshtml 中删除了对象,但我想在调用我的 controller.api 的 $scope.deleteRegister 方法中做出承诺,让对象继续使用相同的方法bd/中的数据值但带有一个标志设置为true,点击图标删除记录后。 首先填充寄存器的代码肯定是检查标志 isDelete = false 吗?你能用 $scope.GetAllRegisters() 代码更新你的问题吗【参考方案3】:

现在我已经知道如何从我的 View.index 中删除一条记录了,它在我的 controller.js 中有拼接

$scope.deleteRegister = function (index) 

    $scope.registers.splice(index, 1);
    $http(
        method: 'PUT',
        url: 'http://localhost:51734/api/UserAPI/',
    ).then(function (res) 
        alert('Exc');
        $scope.GetAllRegisters();
    )

;

但我无法让它与我在我的 controller.api 中的方法进行通信,我只想在我的 UI 上单击删除按钮后更改标志 isDelete = true。

我的控制器.api

//DELETE: api/UserAPI/5
    [HttpPut]
    [Route("api/UserAPI")]
    public HttpResponseMessage Delete(int userId)
    
        try
        
            var foundUser = ctx.User.Find(userId);

            if (foundUser != null)
            
                foundUser.IsDelete = true;
                ctx.SaveChanges();
                return Request.CreateResponse(HttpStatusCode.OK);
            

还有我的 view.index

      <tr ng-repeat="(index, register) in registers">
        <td>
          <a href="" ng-click="deleteRegister()" class="glyphicon glyphicon-trash"></a>
         </td>
      </tr>

【讨论】:

以上是关于从表中删除一行并将布尔标志传递给 API,而不删除实际对象的主要内容,如果未能解决你的问题,请参考以下文章

SnowFlake 存储过程根据条件从表中删除一行

MySQL 从表中删除所有行并将 ID 重置为零

MySQL 从表中删除所有行并将 ID 重置为零

从表中删除具有最大日期的行

从页面中删除行而不刷新页面

使用 Mybatis 将布尔参数传递给存储过程