DDD: Первичные ключи (Ids) и ORMs (например, NHibernate)

Почему бы не добавить фоновое изображение в качестве класса CSS для вашего тега <body>, который вы можете определить в глобальном файле styles.css, а затем на странице / маршруте, который вы хотели бы показать, добавьте этот класс имя тегу <body>, используя один из этих двух вариантов.

Первый вариант самый простой, но менее рекомендуемый:

constructor(@Inject(DOCUMENT) private document: Document) {}

ngOnInit(){
   this.document.body.classList.add('test');
}

Второй вариант (моя личная рекомендация) - реализовать пользовательский класс рендеринга из пакета @angular/core:

import { Component, OnDestroy, Renderer2 } from '@angular/core';

export class myCoolComponent implements OnDestroy {

  constructor(private renderer: Renderer2) {
    this.renderer.addClass(document.body, 'test');
   }

  ngOnDestroy() {
    this.renderer.removeClass(document.body, 'test');
  }

Надеюсь, это поможет вам!

17
задан Andrey Shchekin 1 September 2009 в 13:32
поделиться

8 ответов

Я просто могу поговорить о NHibernate. Там вам понадобится поле для первичного ключа, вам решать, если вы берете бизнес-данные (не рекомендуется) или суррогатный ключ, не имеющий коммерческого значения.

Типичные сценарии:

  • автоматически увеличивающееся значение, генерируемое базой данных
  • guid, сгенерированный NHibernate
  • guid, сгенерированный бизнес-логикой

Наличие уникального идентификатора дает большое преимущество. Когда вы передаете свой объект, например клиенту и обратно на сервер, вы не можете полагаться на идентичность памяти. Вы даже можете иметь в памяти несколько экземпляров одного и того же бизнес-экземпляра. Бизнес-экземпляр идентифицируется идентификатором.

Сравнение на основе идентификатора - дело вкуса. Лично мне нравится простой и надежный код, а сравнение на основе идентификаторов просто и надежно, в то время как глубокое сравнение всегда немного рискованно, подвержено ошибкам и не обслуживается. Таким образом, вы получаете оператор ==, сравнивающий идентичность памяти, и Equals, сравнивающий идентичность бизнеса (и базы данных).

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

NH не требует наличия этих свойств. (однако для этого требуется одно из свойств в качестве первичного ключа.) Но учтите:

  • Он просто работает лучше, например. пессимистическая блокировка возможна только с соответствующим свойством,
  • быстрее: int id работают лучше во многих базах данных, чем другие типы данных
  • и проще: использование свойств, имеющих значение для бизнеса, не рекомендуется по нескольким причинам.

Так зачем делать вашу жизнь тяжелее, чем необходимо?


Изменить: Просто прочтите документацию и обнаружите, что NHibernate делает не требуется свойство id в постоянном классе! Если у вас нет идентификатора , вы не сможете использовать некоторые функции . Рекомендуется иметь, это просто облегчает жизнь.

4
ответ дан 30 November 2019 в 14:43
поделиться

Обычно у вас не будет единственной истинной модели предметной области . У вас будет бесчисленное количество одновременных и последовательных сеансов, которые необходимо координировать, и каждый из которых содержит в себе свою собственную миниатюрную изолированную модель транзакционной области. У вас не будет одного и того же экземпляра объекта между двумя одновременными или между двумя последовательными сеансами. Но вам понадобится какой-то способ гарантировать, что вы можете перемещать информацию из одного сеанса в другой.

Примером, конечно же, является пара URL-адресов / resource / list и / resource / show / id (соответствующая соответствующей паре действий контроллера в asp.net mvc). Переходя от одного к другому, есть два полностью независимых сеанса, но они должны обмениваться данными (через HTTP и браузер) друг с другом.

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

Однородности объектов недостаточно, потому что объекты не одинаковы между сеансами, даже если лежащие в основе концептуальные сущности, которые они представляют, одинаковы юридическое лицо.

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

Однородности объектов недостаточно, потому что объекты не одинаковы между сеансами, даже если лежащие в основе концептуальные сущности, которые они представляют, одинаковы юридическое лицо.

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

Однородности объектов недостаточно, потому что объекты не одинаковы между сеансами, даже если лежащие в основе концептуальные сущности, которые они представляют, одинаковы юридическое лицо.

3
ответ дан 30 November 2019 в 14:43
поделиться

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

Вы можете использовать естественную идентичность, но это подвержено ошибкам.

Просто переименуйте Id в Identity. В доменной модели это выглядит лучше.

Сущности называются сущностями, потому что у них есть идентичность.

0
ответ дан 30 November 2019 в 14:43
поделиться

Обычно я включаю Id в домен как базовый класс сущности. Я не знаю другого способа использовать ORM.

Объект в домене уже уникален по своей ссылке, использование идентификатора для определения уникальности / равенства на самом деле не так уж и отличается на практике. Я пока не столкнулся с серьезным побочным эффектом этого подхода.

0
ответ дан 30 November 2019 в 14:43
поделиться

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

0
ответ дан 30 November 2019 в 14:43
поделиться

В Nh нельзя использовать ссылочное равенство для отсоединенных экземпляров. Это дает вам возможность использовать NH в клиентах, которые хотели бы использовать такое поведение (на мой взгляд, это правильное поведение, NH не зависит от магии!).

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

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

class SomeEntityWithNoId
{
public  blah etc {}
}

class dao
{

void DateMethod()
{
var s1 = sessionFactory.OpenSession();
var instance = new SomeEntityWithNoId();
instance.Blah = "First time, you need to insert";
s1.Save(s1); //now instance is persisted, has a DB ID such as identity or Hilo or whatever
s1.close();
var s2 = sessionFactory.OpenSession();
s2.Blah = "Now update, going to find that pretty hard as the 2nd session won't know what ID to use for the UPDATE statement";

s2.Update(instance); //results in boom! exception, the second session has no idea *how* to update this instance.




}
}

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

Я думаю, что вы правы насчет идентификационных карт, по крайней мере, в отношении NH. Если экземпляр является временным, когда он впервые присоединяется к сеансу, вашему типу не нужно хранить свой идентификатор базы данных в поле. Я думаю, что сессия будет знать, как управлять своими отношениями с db. Я уверен, что вы можете провести тест, чтобы доказать это поведение; p

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

Я думаю, что вы правы насчет идентификационных карт, по крайней мере, в отношении NH. Если экземпляр является временным, когда он впервые присоединяется к сеансу, вашему типу не нужно хранить свой идентификатор базы данных в поле. Я думаю, что сессия будет знать, как управлять своими отношениями с db. Я уверен, что вы можете провести тест, чтобы доказать это поведение; p

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

Я думаю, что вы правы насчет идентификационных карт, по крайней мере, в отношении NH. Если экземпляр является временным, когда он впервые присоединяется к сеансу, вашему типу не нужно хранить свой идентификатор базы данных в поле. Я думаю, что сессия будет знать, как управлять своими отношениями с db. Я уверен, что вы можете провести тест, чтобы доказать это поведение; p

Я думаю, что вы правы насчет идентификационных карт, по крайней мере, в отношении NH. Если экземпляр является временным, когда он впервые присоединяется к сеансу, вашему типу не нужно хранить свой идентификатор базы данных в поле. Я думаю, что сессия будет знать, как управлять своими отношениями с db. Я уверен, что вы можете провести тест, чтобы доказать это поведение; p

Я думаю, что вы правы насчет идентификационных карт, по крайней мере, в отношении NH. Если экземпляр является временным, когда он впервые присоединяется к сеансу, вашему типу не нужно хранить свой идентификатор базы данных в поле. Я думаю, что сессия будет знать, как управлять своими отношениями с db. Я уверен, что вы можете провести тест, чтобы доказать это поведение; p

1
ответ дан 30 November 2019 в 14:43
поделиться

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

Узнайте о них здесь

-1
ответ дан 30 November 2019 в 14:43
поделиться

предполагая, что ваш идентификатор является вашим первичным ключом, вы не сможете сохранить какие-либо данные обратно в БД без него.
Что касается equals и GetHashCode, они предназначены для упорядочивания в списках, где вы создаете индивидуальный порядок.

Спасибо за ответы.

Некоторые из них предполагают, что наличие идентификатора - это единственный способ для ORM создать базу данных Обновить. Я не думаю, что это так. ORM уже отслеживает все объекты, загруженные из БД, поэтому он должен легко получить внутренний идентификатор, когда он понадобится.

Я был бы очень удивлен, если бы это было так. Обычно он создает оператор вставки только из определенных вами свойств.

0
ответ дан 30 November 2019 в 14:43
поделиться
Другие вопросы по тегам:

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