Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C级设计-我应该考虑在哪里放置“?”项目“;班_C#_Asp.net_.net_Class Design_Hierarchy - Fatal编程技术网

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

C# C级设计-我应该考虑在哪里放置“?”项目“;班,c#,asp.net,.net,class-design,hierarchy,C#,Asp.net,.net,Class Design,Hierarchy,我正在为项目管理应用程序创建类库。我将向您简要介绍如何设置所有实体以帮助解决问题 用户在注册期间订阅计划。每个计划都包含模块/应用程序,他可以在成功验证其帐户后使用项目、公司和计划是我正在为其创建类库的模块,这些模块存在于用户生命周期的每个阶段。角色决定用户可以执行或不执行的操作。每个公司(一个用户只有一个)可以容纳许多项目,每个项目都有专门的项目负责人和他的资源。Project Lead是另一个具有更高权限/角色的用户。现在是令人困惑的部分,因为我觉得两者都很好:我应该遵循1还是2 1. 用户

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

用户
在注册期间订阅
计划
。每个计划都包含
模块/应用程序
,他可以在成功验证其帐户后使用<代码>项目、
公司
计划
是我正在为其创建类库的模块,这些模块存在于用户生命周期的每个阶段。角色决定用户可以执行或不执行的操作。每个公司(一个用户只有一个)可以容纳许多项目,每个项目都有专门的项目负责人和他的资源。Project Lead是另一个具有更高权限/角色的用户。现在是令人困惑的部分,因为我觉得两者都很好:我应该遵循1还是2

1.
用户
-订阅(列表)
-项目(列表)
-客户(客户)
-ProjectLead(用户)
-资源(清单)
2.
应用程序
-项目(列表)
-客户(客户)
-ProjectLead(用户)
-资源(清单)
使用者
-GetProjects(列表)
混淆几乎不到这一点,客户机通过外键projectd与项目相关联。因此,在为客户端创建类时

要指示客户属于哪个项目,我应该创建一个
项目吗
类
在客户端类内,还是客户端应位于 项目课


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

选项1:用户有项目(他是项目负责人) 选项2:一个项目有一个用户(即负责人)

还有更多

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

因为您讨论的是外键,所以我是否正确地假设您使用后端数据库来持久化对象?在这种情况下,可以使用类似于对象关系数据库映射器(ORM)的实体框架。如果没有,你必须自己做一些工作,这是我个人避免的;)

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

例子: 您有两张桌子:

  • 使用者
    • id:int
    • 姓名:nvarchar(50)
  • 计划
    • id:int
    • LeadUserId:Users.id的int外键
    • 姓名:nvarchar(50)
实体框架将把它转换成如下两个类

  • 使用者

    • id:int
    • 名称:string
    • 项目:列表
  • 计划

    • id:int
    • 名称:string
    • 用户:用户
例如,现在将项目对象的“用户”字段设置为其他用户时,该项目将自动从原始用户的项目列表中删除,并添加到新用户的项目列表中

您可以通过对数据库上下文对象调用.SaveChanges()方法来持久化对数据库的更改

编写自己的双向关联 双向关系的主要问题是必须保持一致性。对于简单的一对一关系来说并不坏,但是对于一对多关系(就像这里的情况一样,一个用户对多个项目),它有点困难

下面是一个使用相当优秀的ObservableCollection类的实现

项目类 用户类
公共类用户{
公共字符串名称{get;set;}
私有ObservableCollection_projects=新ObservableCollection();
公共可观测集合项目{get{return\u Projects;}}
公共用户(){
Projects.CollectionChanged+=OnProjectCollectionChanged;
}
ProjectCollectionChanged上的受保护无效(对象发送方,NotifyCollectionChangedEventArgs e){
var projects=发送方为IEnumerable;
开关(电动){
案例NotifyCollectionChangedAction。添加:
foreach(项目中的var项目){
如果(project.LeadUser!=此){
project.LeadUser=这个;
}
}
打破
案例通知收集更改操作。移动:
打破
案例NotifyCollectionChangedAction。删除:
foreach(项目中的var项目){
如果(project.LeadUser==此){
project.LeadUser=null;
}
}
打破
案例通知收集更改操作。替换:
打破
案例通知CollectionChangedAction.Reset:
打破
违约:
打破
}
}
}

希望这篇文章对你有用。

让我重新启动电脑,然后我可以添加一些代码示例;-)嗯,事实证明,编写自己的双向关联并不是那么简单。。。我已经更新了我的答案。说得很好。项目不使用任何ORM,所以我们必须自己做。我们编写了以xml作为输出响应的存储过程(yup层次结构得到了很好的维护)&我们必须解析它以转换为项目,用户。
User

  - Subscriptions ( List<> )

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

   - Projects ( List<> )

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

User

  - GetProjects ( List <Project> )
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;
        }
    }
}