【问题标题】:How can i prevent editing a Parent object if it has been assigned to a child object in my asp.net MVc web application如果已将父对象分配给我的 asp.net MVc Web 应用程序中的子对象,我如何防止编辑父对象
【发布时间】:2012-05-04 13:26:06
【问题描述】:

我有两个对象:-

LabTest
LabTestDetails

LabTest 对象可以有零个或多个 LabTestDetails 对象。 我需要实现以下业务规则:-

如果已将 LabTest 对象分配给一个或多个 LabTestDetails 对象,则用户不应对其进行编辑。

目前我已经在 LabTest 对象上实现了一个名为 IsAlreadyAssigned 的辅助方法(以检查 LabTest 对象是否已分配给任何 LabTestDetails 对象):-

public partial class LabTest 
    {    
public bool IsAlreadyAssigned(int id)
            {

                return (LabTestDetailss.Any(r2 => r2.LabTestID == id));

            }}

然后我在Get & Post编辑操作方法上添加了以下检查:-

  public ActionResult Edit(int id)
    {


        LabTest c = repository.GetLabTest (id);

        if ((c == null) ||  (c.IsAlreadyAssigned (id)))
        {
            return View("Error");
        }

        return View(c);
    }

    [HttpPost]
    public ActionResult Edit(int id, FormCollection colletion)
    {

       LabTest c = repository.GetLabTest (id);
       if ((c == null) ||  (c.IsAlreadyAssigned (id))) // *******
        {
            return View("Error");
       }
        try
        {
            if (TryUpdateModel(c))
            {

                elearningrepository.Save();
                return RedirectToAction("Details", new { id = c.LabTestID });
            }
        }

上面的方法在大多数情况下都可以正常工作,但是如果 LabTest 对象只是在 if ((c == null) || (c.IsAlreadyAssigned (id))) 检查后操作方法后被另一个用户分配给 labTestDetails 对象,我将其标记为( *) 上的代码,那么我的业务逻辑就会被破坏。

那么有没有办法实现我的操作方法,以便它始终阻止编辑 LabTest 对象,如果它已分配给 LabTestdetail 对象。

BR

【问题讨论】:

  • 如果您在后台使用 Linq to Sql 或实体框架,那么您可以通过并发检查来做到这一点
  • 我正在使用实体框架,但它不处理这种情况;由于此业务规则未实施,也无法在数据库级别实施..因此 EF 将无法检测到此类情况。
  • 你是说不能在数据库级别实现?你愿意使用存储过程吗?
  • @MisterJames 正是我的想法
  • 是的,我可以使用存储过程,但是如何使用存储过程来实现这个业务逻辑?

标签: asp.net asp.net-mvc-3 entity-framework-4


【解决方案1】:

您可以按照 cmets 中的建议使用存储过程,但您也可以创建一个服务方法来检查是否分配了 LabTest,例如

public bool LabTestIsAssigned(int labTestId)
{
    using (var context = new YourContext())
    {
        return context.LabTestDetails.Any(d => d.LabTestID == id);
    }
}

使用这种方法而不是使用导航属性的好处是可以保证反映数据库的当前状态。

请注意,您还必须在保存更改之前进行此检查!即使这样,也可能会在评估检查之后和保存更改之前立即发生插入。

【讨论】:

  • 表示使用service方法并不能保证100%对象还没有被赋值!!!我说的对吗?
  • 是的,这是真的。可以使用锁定的存储过程是使其无懈可击的唯一可能性。或者,当您在一个事务中添加或删除 LabTestDetails 时,您必须更新 LabTest 记录(带有版本控制)。
猜你喜欢
  • 2014-10-19
  • 2016-05-27
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
  • 1970-01-01
  • 2016-12-05
  • 1970-01-01
相关资源
最近更新 更多