C# 类设计 - 我应该考虑将“项目”放在哪里班级

发布于 2024-12-28 02:42:15 字数 1003 浏览 0 评论 0原文

我正在为项目管理应用程序创建一个类库。我将向您介绍如何设置所有实体来帮助解决相关问题。

用户在注册期间订阅计划。每个计划都包含他可以在成功验证其帐户后使用的模块/应用程序ProjectCompanyPlans 是我为其创建类库的模块,这些模块存在于用户的每个阶段生命周期。角色决定用户可以执行或不可以执行的操作。每个公司(一个用户只能拥有一个)可以容纳许多项目,每个项目都有专门的项目负责人及其资源。项目负责人是另一个具有更高权限/角色的用户。现在这是令人困惑的部分,因为两者对我来说都很好:我应该遵循哪个类层次结构 12

1

User

  - Subscriptions ( List<> )

  - Projects ( List<> )
      - Client ( Client )
      - ProjectLead( User )
      - Resources(List<>)

2

Application

   - Projects ( List<> )

     - Client ( Client )
     - ProjectLead ( User )
     - Resources ( List<> )

User

  - GetProjects ( List <Project> )

混乱几乎没有达到这一点,客户端是通过外键 ProjectId 与项目关联。因此,在为 Client 创建类时,

表示客户端属于哪个项目,我应该创建一个项目 客户端类中的类或客户端是否应该位于 项目类。

I am creating a class library for a project management application. I will brief you on how all the entities are setup to aid in question.

A user subscribes to a plan during registration. Every plan contains modules/applications he can use after successful verification of his account. Project, Company and Plans are the modules for which i am creating the class library and these are the modules that exist at every stage of the user life cycle. Roles determine what the user can perform or not. Each company(only one for a user) can house many projects and each project have dedicated Project Lead with his resources. Project Lead is another user with higher privileges/Roles. Now here is the confusing part because both seems fine to me:Which of the class hierarchy i should follow 1 or 2

1

User

  - Subscriptions ( List<> )

  - Projects ( List<> )
      - Client ( Client )
      - ProjectLead( User )
      - Resources(List<>)

2

Application

   - Projects ( List<> )

     - Client ( Client )
     - ProjectLead ( User )
     - Resources ( List<> )

User

  - GetProjects ( List <Project> )

Confusion barely comes to this point, the client is associated with project through foreign key ProjectId. So while creating a class for Client ,

to denote which project the client belongs should i create a Project
Class
inside Client class or Should client be housed inside the
Project Class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无妨# 2025-01-04 02:42:15

我是否正确理解您对哪个对象应该与另一个对象有关系感到困惑,如下所示:

选项 1:用户有项目(他是领导者)
选项 2:一个项目有一个用户(即领导者)

等等。

好消息是:您不必选择。您可以编写双向关系。
有几种方法可以实现这一点。

因为您谈论外键,所以我假设您正在使用后端数据库来保存对象是否正确?在这种情况下,您可以使用对象关系数据库映射器 (ORM),例如实体框架。如果没有,您将不得不自己做一些工作,这是我个人会避免的事情;)

实体框架

您只需首先编写包含所有关系的数据库,然后让实体框架为您生成相应的类。所有这些类都具有双向关系。

示例:

您有两个表:

  • Users
    • id:整数
    • 名称:nvarchar(50)
  • 项目
    • id:整数
    • LeadUserId:Users.id 的 int 外键
    • 名称:nvarchar(50)

实体框架会将其转换为两个类,如下所示

  • User

    • id:整数
    • 名称:字符串
    • 项目:列表
  • 项目

    • id:整数
    • 名称:字符串
    • 用户:用户

例如,当您现在将项目对象的“用户”字段设置为其他用户时,该项目会自动从原始用户的项目列表中删除,并且添加到新用户的项目列表中。

您可以通过在数据库上下文对象上调用 .SaveChanges() 方法来保留对数据库的更改。

编写您自己的双向关联

双向关系的主要问题是您必须保持一致性。对于简单的一对一关系,情况并没有那么糟糕,但是对于一对多关系(就像这里的情况,一个用户对应多个项目),情况就有点困难了。

下面你会发现一个使用相当优秀的 ObservableCollection 类的实现。

项目类

public class Project {
    public string Name { get; set; }

    private User _leadUser;
    public User LeadUser {
        get { return _leadUser; }
        set {
            if (_leadUser != value) {
                if (_leadUser != null) {
                    _leadUser.Projects.Remove(this);
                    if (!value.Projects.Contains(this)) {
                        value.Projects.Add(this);
                    }
                }
                _leadUser = value;
            }
        }
    }
}

用户类

public class User {

    public string Name { get; set; }

    private ObservableCollection<Project> _projects = new ObservableCollection<Project>();
    public ObservableCollection<Project> Projects { get { return _projects; } }

    public User() {
        Projects.CollectionChanged += OnProjectCollectionChanged;
    }

    protected void OnProjectCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
        var projects = sender as IEnumerable<Project>;
        switch (e.Action) {
            case NotifyCollectionChangedAction.Add:
                foreach (var project in projects) {
                    if (project.LeadUser != this) {
                        project.LeadUser = this;
                    }
                }
                break;
            case NotifyCollectionChangedAction.Move:
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (var project in projects) {
                    if (project.LeadUser == this) {
                        project.LeadUser = null;
                    }
                }
                break;
            case NotifyCollectionChangedAction.Replace:
                break;
            case NotifyCollectionChangedAction.Reset:
                break;
            default:
                break;
        }
    }
}

希望这篇文章对您有用。

Do I understand correctly that you are confused which object should have a relation with another object, like this:

option 1: a user HAS projects (where he is the LEAD)
option 2: a project HAS a user (which is the lead)

And more of that.

The good news is: you don't have to choose. You can write a bidirectional relationship.
There are several ways to implement this.

Because you talk about foreign keys, am I right in assuming you are using a backend database to persist the objects? In that case, you can use an Object-Relational database Mapper (ORM) like Entity Framework. If not, you'll have to do some work yourself, which is something I'd personally avoid ;)

Entity framework

You just write your database with all relationships first and then let entity framework generate the corresponding classes for you. All these classes have bidirectional relationships.

Example:

You have two tables:

  • Users
    • id: int
    • Name: nvarchar(50)
  • Projects
    • id: int
    • LeadUserId: int FOREIGN KEY to Users.id
    • Name: nvarchar(50)

Entity framework will translate this into two classes like this

  • User

    • id: int
    • Name: string
    • Projects: List
  • Project

    • id: int
    • Name: string
    • User: User

When you now for example set the 'User' field of a Project object to a different user, the project is automatically removed from the Projects list of the original user, and is added to the new user's Projects list.

You can persist changes to the database by calling a .SaveChanges() method on the database context object.

Write your own bi-directional association

The main problem with bi-directional relations is that you have to maintain consistency. With simple one-to-one relationships it's not that bad, but with one-to-many relationships (as is the case here, one user to many projects) it's a bit more difficult.

Below you find an implementation that uses the rather excellent ObservableCollection class.

The Project class

public class Project {
    public string Name { get; set; }

    private User _leadUser;
    public User LeadUser {
        get { return _leadUser; }
        set {
            if (_leadUser != value) {
                if (_leadUser != null) {
                    _leadUser.Projects.Remove(this);
                    if (!value.Projects.Contains(this)) {
                        value.Projects.Add(this);
                    }
                }
                _leadUser = value;
            }
        }
    }
}

The User class

public class User {

    public string Name { get; set; }

    private ObservableCollection<Project> _projects = new ObservableCollection<Project>();
    public ObservableCollection<Project> Projects { get { return _projects; } }

    public User() {
        Projects.CollectionChanged += OnProjectCollectionChanged;
    }

    protected void OnProjectCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
        var projects = sender as IEnumerable<Project>;
        switch (e.Action) {
            case NotifyCollectionChangedAction.Add:
                foreach (var project in projects) {
                    if (project.LeadUser != this) {
                        project.LeadUser = this;
                    }
                }
                break;
            case NotifyCollectionChangedAction.Move:
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (var project in projects) {
                    if (project.LeadUser == this) {
                        project.LeadUser = null;
                    }
                }
                break;
            case NotifyCollectionChangedAction.Replace:
                break;
            case NotifyCollectionChangedAction.Reset:
                break;
            default:
                break;
        }
    }
}

Hopefully this post was useful to you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文