наследование домена в реляционной базе данных - поиск рабочей модели базы данных - PullRequest
0 голосов
/ 22 июля 2009

Целью этого вопроса является прежде всего разработка реляционной схемы БД с учетом объектной модели здесь.

Эта часть системы связана с распределением ресурсов по срокам, осуществляемым Ресурсами (разные категории Сотрудников и Подрядчиков) на Виды деятельности (либо Проект, либо Счет). Ввод данных осуществляется еженедельно, и модель предметной области должна проверять еженедельные записи (~ 5 на ресурс с 200 ресурсами), прежде чем разрешить их сохранение. Запросы из БД должны поддерживать утверждение / анализ Распределений как по видам деятельности, так и по ресурсам.

Я уже использую NHib (& FNH) в более простых частях системы, поэтому вспомогательным объектом для моего основного внимания является выделение других уступок, которые должна сделать модель предметной области ради сохранения этих инструментов. Например:
1) свойства, которые в противном случае не были бы виртуальными, являются виртуальными
2) генерация идентификатора (Entity как базовый класс автоматически генерируется для создания идентификатора (int)

Вот интересующие вас доменные классы, которые протестированы в целях презентации:

 public class Allocation : Entity {
    public virtual ResourceBase Resource { get; private set; }
    public virtual ActivityBase Activity { get; private set; }
  public virtual TimeQuantity TimeSpent { get  private set; }
}

public abstract class AllocatableBase : Entity {
    protected readonly IDictionary<DateTime, Allocation> _allocations = new SortedList<DateTime, Allocation>();

    public virtual IEnumerable<Allocation> Allocations { get { return _allocations.Values; } }

}

public abstract class ResourceBase : AllocatableBase {
    public virtual  string Name { get; protected set; }
    public virtual  string BusinessId { get; protected set; }
    public virtual  string OrganizationName { get; protected set; }
}

// example of a concrete ResourceBase
public sealed class StaffMemberResource : ResourceBase  {
    public StaffMember StaffMember { get; private set; }

    public StaffMemberResource(StaffMember staffMember)
    {
        Check.RequireNotNull<StaffMember>(staffMember);
        UniqueId = GetType().Name + " " + staffMember.Number; // bad smell here
        Name = staffMember.Name.ToString();
        BusinessId = staffMember.Number;
        OrganizationName = staffMember.Department.Name;
        StaffMember = staffMember;
    }
}


public abstract class ActivityBase : AllocatableBase {

    public virtual void ClockIn(DateTime eventDate, ResourceBase resource, TimeQuantity timeSpent) {
        ... add to the set of allocations if valid
    }

    public virtual string Description { get; protected set; }
    public virtual string BusinessId { get; protected set; }
}

// example of a concrete ActivityBase
public sealed class ProjectActivity : ActivityBase {
    public Project Project { get; private set; }

    public ProjectActivity(Project project) {
        Check.RequireNotNull<Project>(project);
        Description = project.Description;
        BusinessId = project.Code.ToString();
        UniqueId = GetType().Name + " " + BusinessId;
        Project = project;
    }
}

Вот исходная структура БД, которую я выкидываю, ища отзывы здесь:

table Allocations (
   AllocationID INT IDENTITY NOT NULL,
   StartTime DATETIME NOT NULL,
   EndTime DATETIME NOT NULL,
   primary key (AllocationID)

      foreign key (ActivityID) 
      foreign key (ResourceID) 

)

table Activities (
   ActivityID INT IDENTITY NOT NULL,
   primary key (ActivityID)

   ActivityType NVARCHAR(50) NOT NULL,

      foreign key (WrappedActivityID) // for lack of a better name right now

)

table Projects (    // example of a WrappedActivity
    ProjectID INT IDENTITY NOT NULL,
   Prefix NVARCHAR(50) null,
   Midfix NVARCHAR(50) null,
   Sequence NVARCHAR(50) null,
   Description NVARCHAR(50) null,
   primary key (ProjectID)
)

table Resources (
   ResourceID INT IDENTITY NOT NULL,
   primary key (ResourceID)

   ResourceType NVARCHAR(50) NOT NULL,

      foreign key (WrappedResourceID) 

) * * тысяча двадцать-один

table FullTimeStaffMembers (  // example of a WrappedResource
    StaffMemberID INT IDENTITY NOT NULL,
   Number NVARCHAR(50) not null unique,
   FirstName NVARCHAR(50) not null,
   LastName NVARCHAR(50) not null,
   DepartmentID INT not null,
   primary key (StaffMemberID)
)

Я пока еще не использую конкретную схему отображения наследования (т. Е. Таблицу на класс и т. Д.), А пытаюсь получить начальную модель БД, которая работает (даже если не оптимально с точки зрения производительности). Я уже с трудом осознаю, что благодаря навыкам БД мои навыки программирования выглядят потрясающе, поэтому все конструктивные отзывы и вопросы приветствуются!

Приветствия
Berryl

1 Ответ

0 голосов
/ 22 июля 2009

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

Но я не понимаю связи между WrappedResourceID и ProjectID. Я предполагаю, что следующий шаблон проектирования поможет вам смоделировать различные виды деятельности, которые имеют некоторые общие атрибуты, но также имеют атрибуты, свойственные данному виду деятельности.

Выполнить веб-поиск по "Обобщающей реляционной модели специализации". Вы получите несколько хороших статей, описывающих этот шаблон. Это паттерн, который обычно не преподается на начальных курсах по разработке БД, но люди, привыкшие к наследованию, должны это знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...