Объекты C #, Интерфейсы и База данных - PullRequest
1 голос
/ 01 января 2009

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

Предположим, базовый класс Contact содержит общие поля, такие как имя контакта (Bill, Fred, Sally) и местоположение (дом, работа и т. Д.). Добавьте интерфейс IPhone (код города, номер телефона, добавочный номер) и интерфейс IEmail (адрес электронной почты, cc), чтобы выделить различия. Затем создайте классы (Phone, Email), которые наследуются от них следующим образом:

    Phone: Contact, IPhone 
    Email: Contact, IEMail

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

    Phone: IContact, IPhone
    Email: IContact, IEMail

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

Ответы [ 5 ]

3 голосов
/ 01 января 2009

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

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

До сих пор у меня не было никаких причин использовать интерфейсы.

1 голос
/ 01 января 2009

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

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 не реализовал бы ни один интерфейс - подклассы реализовали бы соответствующие соответственно.

1 голос
/ 01 января 2009

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

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

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

1 голос
/ 01 января 2009

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

  • Phone IS A Contact
  • Phone HAS A Contact

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

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

0 голосов
/ 01 января 2009

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

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

http://www.db4o.com/

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