C # Class Design - Где я должен рассмотреть возможность размещения класса "Project" - PullRequest
2 голосов
/ 21 января 2012

Я создаю библиотеку классов для приложения управления проектами. Я проинформирую вас о том, как все сущности настроены на помощь в вопросе.

A user подписывается на plan при регистрации. Каждый план содержит modules/applications, которые он может использовать после успешной проверки своей учетной записи. Project, Company и Plans - это модули, для которых я создаю библиотеку классов, и это те модули, которые существуют на каждом этапе жизненного цикла пользователя. Роли определяют, что пользователь может выполнять или нет. Каждая компания (только одна для пользователя) может разместить много проектов, и каждый проект имеет выделенного руководителя проекта со своими ресурсами. Project Lead - еще один пользователь с более высоким privileges/Roles. Теперь вот запутанная часть, потому что мне обоим кажется правильным: какой из иерархий классов я должен следовать 1 или 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> )

Путаница едва доходит до этого момента, клиент связан с проектом через внешний ключ ProjectId. Таким образом, при создании класса для клиента,

, чтобы обозначить, к какому проекту принадлежит клиент, если я создам Project Class внутри класса Client или если клиент будет размещен внутри Класс проекта.

1 Ответ

2 голосов
/ 21 января 2012

Правильно ли я понимаю, что вы не понимаете, какой объект должен иметь отношение к другому объекту, например:

вариант 1: пользователь имеет проекты (где он является лидером) вариант 2: у проекта есть пользователь (который является ведущим)

И еще.

Хорошая новость: вам не нужно выбирать. Вы можете написать двунаправленные отношения. Есть несколько способов реализовать это.

Поскольку вы говорите о внешних ключах, правильно ли я полагаю, что вы используете внутреннюю базу данных для сохранения объектов? В этом случае вы можете использовать Object-Relational database Mapper (ORM), такой как Entity Framework. Если нет, то вам придется выполнить какую-то работу самостоятельно, чего я бы лично избегал;)

Структура сущности

Вы просто пишете свою базу данных сначала со всеми связями, а затем позволяете платформе сущностей генерировать соответствующие классы для вас. Все эти классы имеют двунаправленные отношения.

Пример:

У вас есть две таблицы:

  • Пользователи
    • id: int
    • Имя: nvarchar (50)
  • Проекты
    • id: int
    • LeadUserId: int FOREIGN KEY для Users.id
    • Имя: nvarchar (50)

Платформа сущностей преобразует это в два класса, как это

  • Пользователь

    • id: int
    • Имя: строка
    • Проекты: Список
  • Project

    • id: int
    • Имя: строка
    • Пользователь: Пользователь

Когда вы, например, теперь задаете для поля «Пользователь» объекта «Проект» другого пользователя, проект автоматически удаляется из списка «Проекты» исходного пользователя и добавляется в список «Проекты» нового пользователя.

Вы можете сохранить изменения в базе данных, вызвав метод .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;
        }
    }
}

Надеюсь, этот пост был вам полезен.

...