1

Мне нужно реализовать следующее, но я не уверен, что лучший способ:Как реализовать различные типы класса: наследование, интерфейс или свойство класса?

Я создаю функцию сообщения для приложения MVC.

Есть два типа сообщений:

  1. Публичные сообщения
  2. Личные сообщения

Единственное отличие состоит в том, что публичные сообщения имеют поле даты ValidFrom и ValidTo. Я пробовал следующее:

Способ 1, интерфейс Интерфейс IMessage. Два класса PrivateMessage и PublicMessage, которые реализуют интерфейс. PublicMessage имеет два дополнительных свойства. Подключил его к двум различным таблицам с каркасом сущности.

Способ 2, наследование Создайте базовый класс сообщения, в котором есть все поля. Создайте два класса, которые наследуют базовый класс. Может сопоставить класс сообщений с db, поэтому у меня есть только одна таблица для хранения записей. Кажется, я не могу сопоставить интерфейс с EF Code.

Метод 3, Enum свойство, чтобы установить, какой тип сообщения

public enum MessageType 
    { 
     Public = 1, 
     Private = 2, 
    } 

у меня только один класс сообщения, но добавить поле, чтобы показать, какой тип сообщения он. Карты легко переносятся на одну таблицу и легко искать сообщения типа «Public». Я должен сделать мини-обертку вокруг enum, потому что EF не создаст для этого поля в db.

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

Есть ли правильный способ сделать это?

Я использую Entity Framework Code First 4.3.

ответ

2

Структуры ORM обычно решают проблему наследования тремя способами: 1. Одна таблица для всех объектов: в этом подходе есть одна таблица, и каждый конкретный класс будет использовать одну и ту же таблицу. Для определения того, какая запись относится к какому классу, будет использоваться дискриминатор. 2. Одна таблица для каждого конкретного объекта: для каждого конкретного объекта в базе данных будет соответствующая таблица, и каждый объект имеет свою собственную карту. Структура не знает, что эти объекты являются частью иерархии наследования (никакой дискриминатор необходимо) 3. Одна таблица для каждого объекта (конкретная или абстрактная): в этом подходе общие данные хранятся в таблице, которая представляет собой карту для базового абстрактного класса, и каждый конкретный объект будет иметь разделенную таблицу, хранящую свои собственные данные, и есть отношения один к одному между этой таблицей и ее родительской таблицей. В родительской таблице необходим дискриминатор, чтобы показать структуру, записи которой принадлежат к какому объекту.

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

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

+0

Спасибо, что касается первого подхода. Вы бы использовали интерфейс, который наследуют оба класса. Вы знаете, как сопоставить его с той же таблицей в EF (достаточно ли установить modelBuilder.Entity (). ToTable («Сообщения»); modelBuilder.Entity (). ToTable («Сообщения» »); – cfs

+0

на самом деле я не думаю, что вам нужен интерфейс, который может иметь два класса как PublicMessage и PrivateMessage, которые оба наследуются от одного BaseMessage. Я не эксперт EF, а вот статья, которая может помочь: http: // www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application – Beatles1692

+0

Спасибо за ссылку Очень полезно. В последнем вопросе вы бы включили все поля в базовый класс сообщений или только общие поля? Кажется странным иметь свойства класса PrivateMessage, которые он не использует, поэтому я склоняюсь к тому, чтобы иметь общий поля – cfs

1

Вы можете выполнить это по-разному, так как кажется, что вы экспериментируете. Так что ...

1) Вы можете иметь 1 объект Message, содержащий все поля и дополнительный столбец IsPublic 2) Вы можете иметь 2 Entities PublicMessage и PrivateMessage сохранялось в 2 таблицах 3) Вы можете иметь TPT или наследование СНУ модель, в которой у вас есть Message в качестве базового класса PublicMessage и PrivateMessage

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

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

Со всеми этими предположениями я бы выбрал простой и сделал их для разделения объектов. Создание двух запросов для непрочитанных сообщений - это не конец света.

+0

Привет, вы прав насчет запросов, это не самая большая проблема. Размышляя об этом, есть несколько случаев, когда две таблицы будут быстрее, но один запрос, который будет работать много, - «показывать непрочитанные сообщения», как и в StackOverflow ... Вы правы в своем жизненном цикле. Публичные сообщения имеют определенную продолжительность, поэтому я считаю, что он принадлежит к двум классам. Я попытаюсь заставить ORM наилучшим образом отобразить его и не позволять ему определять, как я строю модель домена. – cfs