在控制器中创建多对多模型的模式

Posted

技术标签:

【中文标题】在控制器中创建多对多模型的模式【英文标题】:Pattern to make many to many model creation in a controller 【发布时间】:2012-09-20 22:03:28 【问题描述】:

我正在使用 asp.net mvc 3。我有这样的场景:

    我有用户模型和组模型。一个用户可以有很多组,一个组可以有很多用户。因此,它是多对多关系。 我有一个 UserController 和一个 GroupController。 用户可以创建新组。 我有存储库模式中描述的 UsersRepository 和 GroupsRepository。 GroupController 有一个 Create(Group newGroup) 操作。 一个用户的组不能超过 10 个。 组名必须是唯一的。

问题 1:要处理限制 6,我必须在类 User 上实现 IValidatableObject 并在 User 拥有超过 10 个组时生成验证错误。但是,由于 GroupController 的 Create 动作只接收 Group 作为参数,模型绑定器永远不会调用 User.Validate()。

问题 2:处理限制 7 的唯一方法是根据组存储库中已存在的所有组验证新组名称。因此,此验证必须在 GroupsRepository 中。我说的对吗?

毕竟,我觉得我做错了什么。我的问题是:在我的场景中,实现现有用户创建新组的最佳方法是什么?我应该创建一个像 UserGrougViewModel 这样的视图模型并将其传递给 GroupController 的 Create 操作吗?或者我应该保持 Create(Group newGroup) 操作不变,并在 UserController 上添加一个 CreateGroup(User user) 操作以根据规则 6 验证用户,然后重定向到 GroupController 的操作 Create(Group newGroup)?

【问题讨论】:

【参考方案1】:

问题 1:

不确定是否实现 IValidatableObject,但您可以在用户存储库中创建一个方法,该方法将返回用户所在组的数量。并且,从 GroupController 的 create 方法调用此函数。像这样:

用户存储库


public int GetNumberOfGroupsByUserId(int userId)

   return context.Users.SingleOrDefault(u=>u.Id==userId).Groups.Count;

在创建新组时从 GroupController 使用

    UserRepository userRepo= new UserRepository();
    if(userRepo.GetNumberOfGroupsByUserId(id)>10)
    
      //write code to send error message to view saying the user already has more than 10 groups
    
else

 //go ahead and create new group

问题 2:

处理限制 7 的唯一方法是针对组存储库中已存在的所有组验证新组名称。因此,此验证必须在 GroupsRepository 中。我说的对吗?

不,验证仍然可以在您的 GroupController(或您的业务层)中进行。就像在您的问题 1 中一样,您可以在 GroupRepository 中创建一个方法,如果数据库中已经存在组名,则返回 true,否则返回 false。该方法在 GroupRepository 中看起来像这样

public bool NameExists(string groupName)

 int count=0;
count= context.Groups.Where(g=>g.Name==groupName).Count;
if (count==0)
return false;
else
return true;

在创建新组时从 GroupController 使用

        GroupRepository groupRepo= new GroupRepository();
        if(groupRepo.NameExists(groupName))
        
          //write code to send error message to view saying a group already exists with same name
        
    else
    
     //go ahead and create new group
    

【讨论】:

这是一个很好的解决方案,但我个人不喜欢在控制器操作内部进行验证。此外,请注意,创建新组需要通过将新组添加到用户的组列表来修改用户模型。所以组控制器的create动作是修改用户,不好.. 这只是一个示例,展示了如何在存储库之外进行验证。您可以在业务层中进行验证。我不认为存储库是验证的好地方。我的示例代码根本不修改用户对象。当您说“因此,组控制器的创建操作正在修改用户,这不好..”时,您是什么意思? 你称之为业务层吗?正如我所写,这是多对多的关系。一个用户有很多组。因此,当用户创建组时,我需要将此创建的组添加到用户的组列表中,以便将创建的组固定到用户。这就是整个问题...我不知道实现现有用户创建组的最佳方法。

以上是关于在控制器中创建多对多模型的模式的主要内容,如果未能解决你的问题,请参考以下文章

如何在实体框架中创建多对多映射?

在 Doctrine 中创建多对多关系的最佳实践。

如何创建如何在 typeorm 中创建多对多关系,[NestJS]

如何在rails的同一个表中创建多对多

如何使用 schema.graphql 在放大数据存储中创建多对多关系

使用flask-restplus在flask-SQLAlchemy中创建多对多关联表时出错