Как мне создать DAL, когда мне приходится иметь дело с отношениями?

Скажем, что я разрабатываю трекер ошибок, где билет принадлежит не более одной вехи, а веха может иметь много билетов. Когда веха удаляется (из базы данных), все билеты, связанные с этой вехой, должны иметь взаимозависимость (т. Е. Установить на null). Это простая взаимосвязь.

Классы довольно просты и сопоставляются непосредственно с базой данных:

public class Ticket {
    public ObjectId Id { get; set; }
    public string Title { get; set; }
    public ObjectId MilestoneId { get; set; }
}

public class Milestone {
    public ObjectId Id { get; set; }
    public string Title { get; set; }
}

Теперь наступает сложная часть: где и как я могу сбросить поля MilestoneId? Одним из возможных решений является запись уровня доступа к данным путем создания одного гигантского класса со всеми методами доступа к данным для всех видов объектов, в данном случае билетов и этапов. Другое возможное решение состоит в том, чтобы написать несколько классов (например, TicketProvider и MilestoneProvider), по одному для каждого типа объектов, которые предоставляют методы доступа к данным, такие как Find, Save и Destroy.

Последний обращается ко мне больше, потому что мне не нравятся чудовищные классы, но есть одна оговорка: метод, который удаляет вехи, должен перезагрузить MilestoneId s всех связанных билетов на null. Это означает, что MilestoneProvider, который отвечает за манипулирование вехами, внезапно имеет дело с билетами!

Как отношения обычно рассматриваются в слоях доступа к данным и как я могу предотвратить нарушение SRP? Должен ли я помещать весь DAL в один класс, или я должен его разделить, и если да, то как я могу это сделать?

7 голосов | спросил rightfold 27 ThuEurope/Moscow2012-12-27T08:42:17+04:00Europe/Moscow12bEurope/MoscowThu, 27 Dec 2012 08:42:17 +0400 2012, 08:42:17

2 ответа


2

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

Если вы используете шаблон репозитория, вы можете сделать что-то в этом направлении:

void Delete(int milestoneId)
{
    db.BeginTransaction();
    db.Execute("UPDATE Tickets SET MilestoneID = null WHERE MilestoneID = @p0", milestoneId);
    db.Execute("DELETE FROM Milestones WHERE MilestoneID = @p0", milestoneId);
    db.Commit();
}

Это немного зависит от личных предпочтений, так как вы можете утверждать, что MilestoneRepository не должны знать о билетах, но в зависимости от того, сколько другие требования, которые у вас есть в этих строках (например, если их немного), это может быть приемлемым на данный момент. Другой вариант - создать службу, которая обладает такими знаниями:

class MilestoneRepository
{
    void Delete(int milestoneId)
    {
        db.Execute("DELETE FROM Milestones WHERE MilestoneID = @p0", milestoneId);
    }
}

class TicketRepository
{
    void DetachAllFromMilestone(int milestoneId)
    {
        db.Execute("UPDATE Tickets SET MilestoneID = null WHERE MilestoneID = @p0", milestoneId);
    }
}

class MilestoneService
{
    void Delete(Milestone milestone)
    {
        unitOfWork.Begin(); // start transaction
        ticketRepository.DetachAllFromMilestone(milestone.Id);
        milestoneRepository.Delete(milestone.Id);
        unitOfWork.Complete(); // commit transaction
    }
}
ответил Trevor Pilley 28 FriEurope/Moscow2012-12-28T00:40:17+04:00Europe/Moscow12bEurope/MoscowFri, 28 Dec 2012 00:40:17 +0400 2012, 00:40:17
-4

Создайте свойство readonly в родительском классе, проверьте, является ли восстановленный дочерний идентификатор ниль-ном, увеличивая его или назначая его из db.

ответил Jay Sampat 27 ThuEurope/Moscow2012-12-27T20:37:14+04:00Europe/Moscow12bEurope/MoscowThu, 27 Dec 2012 20:37:14 +0400 2012, 20:37:14

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132