2013-12-12 5 views
1

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

Модель 1

То, что я хотел бы здесь в основном использовать заказы и адреса лиц, чтобы иметь возможность использовать ту же таблицу поиска. Идея таблицы поиска состоит в том, чтобы иметь возможность скрывать/показывать все ордеры или все Адреса для конкретного пользователя, имея свойство в объекте поиска, которое может хранить коллекции общих объектов.

Model 1 entity diagram

enter image description here

Модель 2

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

Спасибо за вашу помощь

Model 2 entity diagram

enter image description here

======= Добавлено 16/12/2013 ==============

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

enter image description here

Теперь, когда я пытаюсь добавить стипендиат, например, он справедливо жалуется, что

«Инструкция INSERT заявление противоречит ограничению внешнего ключа„FK_HonoraryMemberLookup“, который я предполагаю, означает, что он пытается чтобы добавить поиск для двух других типов пользователей и не может из-за нулевых значений.

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

Еще раз спасибо

+0

Я не совсем уверен, что вы действительно оптимизируя здесь. Запрос для получения списка заказов (или адресов) теперь потребует двух JOIN вместо одного. Заказы и адреса довольно ортогональны друг другу, поэтому здесь нет смысла использовать одну иерархию наследования таблицы. Если поле IsPublic немного, вы оптимизируете сохранение одного бита на запись. Едва ли это стоит. –

+0

Спасибо Брайан. Итак, что вы предлагаете, имеет свойство IsPublic bool для объектов Orders and Addresses? Имеет смысл, но так как было бы около 20 других объектов, которым понадобилось бы свойство IsPublic, которое я, почему я пытался объявить его один раз. Думая об этом, возможно, у меня может быть сущность с полем IsPublic, и у ордеров и Адресов наследуется от этого объекта. Это создаст какие-либо проблемы? – user3096080

ответ

1

Я бы рекомендовал вам использовать наследование типа Table-Per-Type для достижения того, что вы хотите сделать. Модель будет выглядеть следующим образом, с Lookup объект помечается как Аннотация

TPT Diagram

Вот несколько примеров кода, которые могли бы использовать эту модель:

class Program 
{ 
    static void Main(string[] args) 
    { 
     using (var container = new UserModelContainer()) 
     { 
      var user = new User 
         { 
          FirstName = "Joe", 
          Surname = "Coder" 
         }; 

      var address = new Address 
          { 
           AddressLine1 = "123 Any Street", 
           AddressLine2 = "Apt 2A", 
           City = "Anytown", 
           StateProvince = "CA", 
           PostalCode = "12345", 
           Country = "United States", 
           IsPublic = false 
          }; 

      user.Lookups.Add(address); 

      container.SaveChanges(); 
     } 

     using (var container = new UserModelContainer()) 
     { 
      foreach (var user in container.Users) 
      { 
       Console.WriteLine("Name: {0} {1}", user.FirstName, user.Surname); 

       foreach (var address in user.Lookups.OfType<Address>()) 
       { 
        Console.WriteLine(address.AddressLine1); 
        Console.WriteLine(address.AddressLine2); 
        Console.WriteLine(address.City); 
        Console.WriteLine(address.StateProvince); 
        Console.WriteLine(address.PostalCode); 
        Console.WriteLine(address.Country); 
        Console.WriteLine("Address is {0}", address.IsPublic ? "Public" : "Private"); 
       } 
      } 
     } 
    } 
} 
+0

Спасибо Брайан, это работает очень хорошо. Я попытался немного расширить эту модель, пожалуйста, найдите подробности в исходном сообщении. У тебя есть идеи? – user3096080

+0

Объект Lookup должен иметь отношения только с пользовательским объектом верхнего уровня, а не с его производными типами. –

+0

Отлично! Это сработало! Большое спасибо за Вашу помощь – user3096080

1

Возможно, вы захотите взглянуть на database normalization. Нормализация вашей модели поможет вам избежать хранения одного и того же фрагмента данных несколько раз (может привести к несогласованности) и уменьшить сложность.

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

Единственное, что содержит таблица Lookup, которая дает основание для существования, это флаг IsPublic. Для чего его используют? Если Lookups - это вещи, которые пользователь может создавать, сохранять и обычно знать как thing, тогда таблица Lookup может быть оправдана, и я бы использовал модель 2. Если таблица поиска существует только для облегчения создания запроса, я бы скорее пропустите его, чтобы максимально упростить модель базы данных.

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

+0

Спасибо Оливер. Идея флага IsPublic - это способ, чтобы пользователи не отображали свою информацию на сайте для каждого объекта. Было бы много сущностей, похожих на Адреса и Ордена, и все они нуждались в свойстве IsPublic, я пытался найти способ наследовать это, поэтому мне нужно объявить его только один раз. От вашего ответа, похоже, было бы проще иметь IsPublic для каждого объекта? Тогда я мог бы, если пользователь решит не показывать свои ордера, выполнить все их заказы и установить IsPublic в false. – user3096080

+0

Кажется, ответ Брайана Дрисколла - это то, что вы ищете, предполагая, что нужно указать IsPublic для каждого объекта Order, каждого объекта Address и т. Д. Если вы хотите указать IsPublic только для категорий (все Адреса, все Заказы и т. д.), тогда я предпочел бы сохранить эту информацию в другом месте. Я не уверен, что было бы наиболее эффективным, но таблицы с тремя столбцами: UserId, CategoryName, IsPublic было бы достаточно для поиска, какие категории показывать или нет. – OliverUv

+0

Спасибо Оливеру за помощь! – user3096080

Смежные вопросы