Объекты C#, интерфейсы и база данных

Как лучше всего писать в базу данных при работе с объектами и интерфейсами? Существует множество мнений относительно объектного дизайна, но я не понимаю, что такое база данных. Простой пример:

Предположим, что базовый класс Contact содержит общие поля, такие как имя контакта (Билл, Фред, Салли) и местоположение (дом, работа и т. д.). Добавьте интерфейс IPhone (код города, номер телефона, добавочный номер) и интерфейс IEmail (адрес электронной почты, копия), чтобы абстрагироваться от различий. Затем создайте классы (Телефон, Электронная почта), которые наследуются от них следующим образом:

    Phone: Contact, IPhone 
    Email: Contact, IEMail

Альтернативой было бы создание интерфейса IContact вместо базового класса Contact следующим образом:

    Phone: IContact, IPhone
    Email: IContact, IEMail

Если не реализовывать NHibernate или Entity Framework, что лучше всего использовать для кода доступа к данным, если эти объекты записываются в одну таблицу базы данных? То, что я увидел, кажется довольно неуклюжим.

Что делать, если у контакта есть телефон и электронная почта? Контакт должен иметь поле "Телефон", содержащее все данные о телефоне, и поле "Электронная почта", содержащее все данные электронной почты. Возможно, вы даже захотите иметь несколько телефонов или адресов электронной почты; но телефон не является контактом, так почему класс Phone расширяет контакт?

configurator 01.01.2009 04:43
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
2 301
5

Ответы 5

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

После этого я использую DAL, способный отражать эти классы и генерировать требуемый SQL на лету; после профилирования мне, возможно, придется создать несколько SP, но его результаты также отправляются принимающему DTO.

Причин для использования интерфейсов я пока не обнаружил.

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

Jason Jackson 01.01.2009 08:06

Это правда, я не думал о насмешках и удалении.

Otávio Décio 01.01.2009 16:04

Думаю, вам нужно рассмотреть отношения между этими тремя сущностями. Произнесите вслух следующие утверждения и посмотрите, какое из них подходит для вашего приложения:

  • PhoneЯВЛЯЕТСЯ А Contact
  • PhoneИМЕЕТ А Contact

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

Однако вас интересует доступ к данным, и вы упомянули, что существует одна таблица базы данных, что заставляет меня задаться вопросом, зачем вам нужны отдельные сущности для Contact, Phone и Email. Я бы порекомендовал вам либо реорганизовать свой код, чтобы включить единый объект для представления вашей модели данных, поскольку это снизит сложность вашей кодовой базы, либо провести рефакторинг вашей схемы базы данных, чтобы отразить то, что, похоже, вы действительно хотите (на основе вашего образца кода).

На самом деле, я бы подумал об этом иначе: у контакта есть телефон.

tvanfosson 01.01.2009 04:32

Это то, о чем я думал сначала, но его модель данных, похоже, наоборот.

Andrew Hare 01.01.2009 05:51

Сначала создайте свою базу данных, чтобы быть уверенным, что вы действительно можете хранить все, что вам нужно. Затем создайте общие запросы, такие как «Все клиенты и их основной номер телефона» и «Один клиент со всеми их номерами телефонов».

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

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

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

Contacts Table
     ContactID
     FirstName
     LastName
     MI
     StreetAddress1
     StreetAddress2
     City
     StateProvince
     PostalCode
     PreferredContactMethod (0 = Phone, 1 = Email)
     ... more details ...

PhoneNumbers Table
     PhoneID
     ContactID
     PhoneNumber
     IsPrimary
     ...more details...

EmailAddresses Table
     EmailID
     ContactID
     EmailAddress
     IsPrimary
     ...more details...

Тогда для ваших классов у вас будет класс Contact, который содержит один или несколько номеров телефона и один или несколько адресов электронной почты. Если у вас есть другие вещи, кроме контактов, у которых есть номера телефонов или адреса электронной почты, тогда может иметь смысл иметь интерфейсы, указывающие, что они являются IPhoneable или IEmailable, то есть просто вы можете добавлять / удалять из них номера телефонов или адреса электронной почты, например :

public interface IPhoneable
{
     public PhoneNumber GetPrimaryNumber();
     public void AddNumber( PhoneNUmber number );
     public IEnumerable<PhoneNumber> GetNumbers();
}

public interface IEmailable
{
     public EmailAddress GetPrimaryAddress();
     public void AddEmailAddress( EmailAddress address );
     public IEnumerable<EmailAddress> GetEmailAddresses();
}

public class Contact : IPhoneable, IEmailable
{
     private List<PhoneNumber> phoneNumbers;
     private List<EmailAddresses> emailAddresses;

     public int ContactID { get; private set; }
     public string FirstName { get; set; }
     ...

     public Contact()
     {
         this.phoneNumbers = new List<PhoneNumber>();
         this.emailAddresses = new List<EmailAddress>();
     }

     public PhoneNumber GetPrimaryNumber()
     {
          foreach (PhoneNumber number in this.phoneNumbers)
          {
               if (number.IsPrimary)
               {
                    return number;
               }
          }
          return null;
      }

      ...
}

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

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

«Db4o - это объектная база данных с открытым исходным кодом, которая позволяет разработчикам Java и .NET сохранять и извлекать любой объект приложения, включая тематические карты, с помощью только одной строчки кода, устраняя необходимость предварительно определять или поддерживать отдельную жесткую модель данных».

http://www.db4o.com/

Другие вопросы по теме