[Entity Framework]
От: syomin  
Дата: 02.06.10 05:33
Оценка:
Добрый день!

Только начинаю осваивать Entity Framework, поэтому вопрос в общем-то дилетантский...

Построил я модель предметной области по существующей базе данных с использование мастера из состава Visual Studio. В базе данных есть две таблицы: Customers и Products, для каждой из них определен первичный ключ (поле Id типа Guid). В таблице Products также имеется поле CustomerId и соответствующий внешний ключ, который связывает обе таблицы.

Для примера рассмотрим класс Product, который сгенерировал нам мастер:
public partial class Product : EntityObject
{
        public Guid Id
        {
            get { ... }
            set { ... }
        }

        public Guid CustomerId
        {
            get { ... }
            set { ... }
        }

        public Customer Customer
        {
            get { ... }
            set { ... }
        }
}


На мой взгляд, свойства Id и CustomerId избыточны и им не место в этом классе, поскольку они имеют отношение только к тому, каким образом данный объект хранится в базе данных. От них как-нибудь можно избавиться?
Re: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 08:17
Оценка: 1 (1) +3 :)))
Здравствуйте, syomin, Вы писали:

S>Добрый день!


S>Только начинаю осваивать Entity Framework, поэтому вопрос в общем-то дилетантский...


S>Построил я модель предметной области по существующей базе данных с использование мастера из состава Visual Studio. В базе данных есть две таблицы: Customers и Products, для каждой из них определен первичный ключ (поле Id типа Guid). В таблице Products также имеется поле CustomerId и соответствующий внешний ключ, который связывает обе таблицы.


S>Для примера рассмотрим класс Product, который сгенерировал нам мастер:

S>
S>public partial class Product : EntityObject
S>{
S>        public Guid Id
S>        {
S>            get { ... }
S>            set { ... }
S>        }

S>        public Guid CustomerId
S>        {
S>            get { ... }
S>            set { ... }
S>        }

S>        public Customer Customer
S>        {
S>            get { ... }
S>            set { ... }
S>        }
S>}
S>


S>На мой взгляд, свойства Id и CustomerId избыточны и им не место в этом классе, поскольку они имеют отношение только к тому, каким образом данный объект хранится в базе данных. От них как-нибудь можно избавиться?


1)Написать свой ORM
2)Сделать свойства private
3)Включить мозг и понять что убрав эти свойства ты не сможешь написать Linq запрос, который вытянет Product по Id или все Product для одного Customer.
Потом сжечь все книги по ООП и выкинуть фаулера АКПП.
Re[2]: [Entity Framework]
От: syomin  
Дата: 02.06.10 08:52
Оценка:
G>1)Написать свой ORM
Хотелось бы использовать готовый.

G>2)Сделать свойства private

Некошерно. Я же знаю, что они там есть и это претит моему чувству прекрасного.

G>3)Включить мозг и понять что убрав эти свойства ты не сможешь написать Linq запрос, который вытянет Product по Id или все Product для одного Customer.

Вы слишком узко смотрите на вещи. Первичный ключ используется базой данных для однозначной идентификации строки в таблице. Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы данных, то перечисленных выше полей быть не должно — достаточно просто ссылок. Думаю, технически это возможно. Другое дело, возможно ли это в EF.

G>Потом сжечь все книги по ООП и выкинуть фаулера АКПП.

Не конструктивно.
Re[2]: [Entity Framework]
От: QrystaL Украина  
Дата: 02.06.10 09:01
Оценка:
Здравствуйте, gandjustas, Вы писали:
G>... сжечь все книги по ООП ...

Рукописи не горят
Re[3]: [Entity Framework]
От: HowardLovekraft  
Дата: 02.06.10 09:16
Оценка:
Здравствуйте, syomin, Вы писали:

S>Первичный ключ используется базой данных для однозначной идентификации строки в таблице. S>Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы S>данных, то перечисленных выше полей быть не должно — достаточно просто ссылок.

В предметной области объекты идентифицировать не нужно?
Re[4]: [Entity Framework]
От: syomin  
Дата: 02.06.10 09:25
Оценка: :)
Здравствуйте, HowardLovekraft, Вы писали:

HL>Здравствуйте, syomin, Вы писали:


S>>Первичный ключ используется базой данных для однозначной идентификации строки в таблице. S>Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы S>данных, то перечисленных выше полей быть не должно — достаточно просто ссылок.

HL>В предметной области объекты идентифицировать не нужно?

Отдельным идентификатором? Нет, достаточно просто ссылки на объект.
Re[5]: [Entity Framework]
От: HowardLovekraft  
Дата: 02.06.10 09:29
Оценка: :))
Здравствуйте, syomin, Вы писали:

S>Здравствуйте, HowardLovekraft, Вы писали:


HL>>Здравствуйте, syomin, Вы писали:


S>>>Первичный ключ используется базой данных для однозначной идентификации строки в таблице. S>Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы S>данных, то перечисленных выше полей быть не должно — достаточно просто ссылок.

HL>>В предметной области объекты идентифицировать не нужно?

S>Отдельным идентификатором? Нет, достаточно просто ссылки на объект.

Хм. Предметная область это "складской учет", "управление производством", "контроль доступа". Идентифицируйте человека ссылкой на объект и расскажите, как это у вас получилось.
Re[6]: [Entity Framework]
От: syomin  
Дата: 02.06.10 09:48
Оценка:
S>>Отдельным идентификатором? Нет, достаточно просто ссылки на объект.
HL>Хм. Предметная область это "складской учет", "управление производством", "контроль доступа". Идентифицируйте человека ссылкой на объект и расскажите, как это у вас получилось.

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


Мне не нужно, чтобы первичный ключ "уходил" из системы дальше слоя работы с БД (например, в какие-то сторонние системы). Ведь что нужно пользователю:
Re[3]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 10:17
Оценка: +1
Здравствуйте, syomin, Вы писали:

G>>1)Написать свой ORM

S>Хотелось бы использовать готовый.
Ксттаи в EF есть возможность свой генератор кода подсунуть — пользуйся. Только потом покажи нам что получилось.

G>>2)Сделать свойства private

S>Некошерно. Я же знаю, что они там есть и это претит моему чувству прекрасного.
"Чувство прекрасного" в нашем деле зачастую противоречит здравому смыслы. Кроме того оно неформализуемо. Ты можешь до посинения доказывать что отсутствие ключей в классе сущности это "прекрасно", но если на форме, где отображается Product надо сделать ссылку на форму Customer, то все равно понадобится внешний ключ в Product или первичный в Customer. Причем в первой версии EF из "чувства прекрасного" не создавались поля внешних ключей, но почему-то включили их в четвертую версию.

G>>3)Включить мозг и понять что убрав эти свойства ты не сможешь написать Linq запрос, который вытянет Product по Id или все Product для одного Customer.

S>Вы слишком узко смотрите на вещи. Первичный ключ используется базой данных для однозначной идентификации строки в таблице. Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы данных, то перечисленных выше полей быть не должно — достаточно просто ссылок. Думаю, технически это возможно.
Плохо думаешь. У обычных ссылок (указателей) слишком короткий срок жизни, чтобы покрыть все сценарии.

S>Другое дело, возможно ли это в EF.

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

G>>Потом сжечь все книги по ООП и выкинуть фаулера АКПП.

S>Не конструктивно.
Зато очень полезно.


Чувство прекрасного надо долго тренировать прежде чем оно перестанет тебя подводить. А чтение литературы по ООП препятствует такой тренировке.
Re[7]: [Entity Framework]
От: drol  
Дата: 02.06.10 10:33
Оценка:
Здравствуйте, syomin, Вы писали:

S>Мне не нужно, чтобы первичный ключ "уходил" из системы дальше слоя работы с БД (например, в какие-то сторонние системы). Ведь что нужно пользователю:

S>
S>1. Список всех сотрудников.
S>2. Список сотрудников, удовлетворяющих определенному критерию (например, с указанной фамилией).

Ну и как Ваш пользователь будете различать сотрудников у которых полностью одинаковые ФИО ?
Re[3]: [Entity Framework]
От: drol  
Дата: 02.06.10 11:14
Оценка:
Здравствуйте, syomin, Вы писали:

S>Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы данных,


Задача ORM'ов — предоставление статически типизированного и, соответственно, проверяемого в compile time доступа к реляционным данным. Именно этого хотели авторы/пользователи ORM'ов с самого начала, но долго не могли сформулировать

S>Думаю, технически это возможно. Другое дело, возможно ли это в EF.


Технически возможно всё. Вопрос тольков том, готовы ли Вы уплатить цену этого технического решения ???
Re[7]: [Entity Framework]
От: HowardLovekraft  
Дата: 02.06.10 11:36
Оценка:
Здравствуйте, syomin, Вы писали:

S>>>Отдельным идентификатором? Нет, достаточно просто ссылки на объект.

HL>>Хм. Предметная область это "складской учет", "управление производством", "контроль доступа". Идентифицируйте человека ссылкой на объект и расскажите, как это у вас получилось.

S>У меня не "складской учет", "управление производством", "контроль доступа".

Не суть важно. Это всего лишь примеры.

S>Опять же, если бы мне нужно было держать в базе данных перечень сотрудников, то сделал бы я S>табличку типа такой:

Фиг с ними, с табличками. Нет табличек. Есть люди. Рано или поздно возникнет задача — отличить одного человека от другого. Как?
Re[8]: [Entity Framework]
От: syomin  
Дата: 02.06.10 12:38
Оценка:
D>Ну и как Ваш пользователь будете различать сотрудников у которых полностью одинаковые ФИО ?

Зависит от условий задачи: дата рождения, место жительства, серия + номер паспорта и т.д. и т.п. Поймите простую вещь: если у нас первичный ключ является суррогатным, то в большинстве случаев никакого смысла показывать его пользователю нет, поэтому и тащить его в приложении дальше слоя доступа к базе данных не нужно.
Re[4]: [Entity Framework]
От: syomin  
Дата: 02.06.10 12:48
Оценка:
G>>>1)Написать свой ORM
S>>Хотелось бы использовать готовый.
G>Ксттаи в EF есть возможность свой генератор кода подсунуть — пользуйся. Только потом покажи нам что получилось.

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

G>>>2)Сделать свойства private

S>>Некошерно. Я же знаю, что они там есть и это претит моему чувству прекрасного.
G>"Чувство прекрасного" в нашем деле зачастую противоречит здравому смыслы. Кроме того оно неформализуемо. Ты можешь до посинения доказывать что отсутствие ключей в классе сущности это "прекрасно", но если на форме, где отображается Product надо сделать ссылку на форму Customer, то все равно понадобится внешний ключ в Product или первичный в Customer.

В этом случае нам по-прежнему не нужен CustomerId в классе Product, поскольку EF генерирует нам свойство Customer, которое является ссылкой на соответствующего customer'а.

G>>>3)Включить мозг и понять что убрав эти свойства ты не сможешь написать Linq запрос, который вытянет Product по Id или все Product для одного Customer.

G>Плохо думаешь. У обычных ссылок (указателей) слишком короткий срок жизни, чтобы покрыть все сценарии.
Мои сценарии покрывает. Вопрос ведь в том как сделать, а не почему нужны идентификаторы.
Re[4]: [Entity Framework]
От: syomin  
Дата: 02.06.10 12:49
Оценка:
D>Задача ORM'ов — предоставление статически типизированного и, соответственно, проверяемого в compile time доступа к реляционным данным. Именно этого хотели авторы/пользователи ORM'ов с самого начала, но долго не могли сформулировать

Эту задачу успешно решает LINQ-To-SQL. У создателей EF были, по их словам, другие цели.
Re[5]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 13:18
Оценка:
Здравствуйте, syomin, Вы писали:

G>>>>1)Написать свой ORM

S>>>Хотелось бы использовать готовый.
G>>Ксттаи в EF есть возможность свой генератор кода подсунуть — пользуйся. Только потом покажи нам что получилось.

S>Про генератор я в курсе, только тут это не поможет. Проблема не в том, чтобы избавиться от идентификаторов, а в том, чтобы переложить заботу о них на EF, оставив себе только ссылки. А тут нужна определенная логика в EF.

EF ориентируется на CSDL, там ключи есть, от этого никуда не денешься. Потому что иначе на eSQL выборку по ключу не напишешь вообще.
Маппинг на объекты — то что отлично контролируется в 4-ой версии.

G>>>>2)Сделать свойства private

S>>>Некошерно. Я же знаю, что они там есть и это претит моему чувству прекрасного.
G>>"Чувство прекрасного" в нашем деле зачастую противоречит здравому смыслы. Кроме того оно неформализуемо. Ты можешь до посинения доказывать что отсутствие ключей в классе сущности это "прекрасно", но если на форме, где отображается Product надо сделать ссылку на форму Customer, то все равно понадобится внешний ключ в Product или первичный в Customer.

S>В этом случае нам по-прежнему не нужен CustomerId в классе Product, поскольку EF генерирует нам свойство Customer, которое является ссылкой на соответствующего customer'а.

И что? Нужна ссылка в виде http://site/action/{а вот тут надо как-то указать кастомера}, если нету ключей в сущностях, то как указывать?


G>>>>3)Включить мозг и понять что убрав эти свойства ты не сможешь написать Linq запрос, который вытянет Product по Id или все Product для одного Customer.

G>>Плохо думаешь. У обычных ссылок (указателей) слишком короткий срок жизни, чтобы покрыть все сценарии.
S>Мои сценарии покрывает. Вопрос ведь в том как сделать, а не почему нужны идентификаторы.
А твои сценарии никого не интересуют. Если нужно чтобы твои покрывало — пиши ORM сам.
Re[9]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 13:20
Оценка:
Здравствуйте, syomin, Вы писали:

D>>Ну и как Ваш пользователь будете различать сотрудников у которых полностью одинаковые ФИО ?


S>Зависит от условий задачи: дата рождения, место жительства, серия + номер паспорта и т.д. и т.п. Поймите простую вещь: если у нас первичный ключ является суррогатным, то в большинстве случаев никакого смысла показывать его пользователю нет, поэтому и тащить его в приложении дальше слоя доступа к базе данных не нужно.


Те то что не показывается пользователю вообще должно отсутствовать в бизнес-логике?
Re[9]: [Entity Framework]
От: drol  
Дата: 02.06.10 13:29
Оценка:
Здравствуйте, syomin, Вы писали:

S>Зависит от условий задачи: дата рождения, место жительства, серия + номер паспорта и т.д. и т.п.


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

S>Поймите простую вещь: если у нас первичный ключ является суррогатным, то в большинстве случаев никакого смысла показывать его пользователю нет,


Ничего подобного. Пользователь может его в виде компоненты http-ссылки наблюдать, например. А уж собственно потрохам приложения PK так и вообще на каждом шагу необходим...
Re[10]: [Entity Framework]
От: syomin  
Дата: 02.06.10 14:13
Оценка:
D>Ну вот видите — указателей/ссылок, даже в элементарном сферовакуумном примере, недостаточно для эффективного обеспечения identity объектов.
В элементарном сферовакуумном примере для обеспечения идентичности объекта может использоваться связка из гражданства и номера паспорта человека. При этом сделать такой первичный ключ для соответствующей таблицы в БД конечно можно, но неудобно, поскольку составной первичный ключ нельзя использовать для описания внешних ключей. В этом случае делают так: накладывают ограничение уникальности на пару полей "гражданство" и "номер паспорта" и добавляют суррогатный первичный ключ — вещь абсолютно синтетическую, которая нужна только на уровне базы данных и слоя доступа к ней.

D>Ничего подобного. Пользователь может его в виде компоненты http-ссылки наблюдать, например.

Я писал, что идентификатор объекта не передается за пределы приложения.

D>А уж собственно потрохам приложения PK так и вообще на каждом шагу необходим...

В описанном случае не нужен. Приложение уже есть и работает, теперь хочется добавить к нему базу данных, чтобы обеспечить персистентность.
Re[5]: [Entity Framework]
От: drol  
Дата: 02.06.10 14:16
Оценка:
Здравствуйте, syomin, Вы писали:

S>Эту задачу успешно решает LINQ-To-SQL.


Поехали по кругу: сие задача всех ORM'ов. То что длительное время люди не могли её внятно сформулировать, и в результате породили таких монстров как Hibernate и EF — это совсем другой вопрос.

S>У создателей EF были, по их словам, другие цели.


А причём тут цели-то ??? Разговор о задачах, а они именно те самые.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.