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[5]: [Entity Framework]
От: HowardLovekraft  
Дата: 02.06.10 09:29
Оценка: :))
Здравствуйте, syomin, Вы писали:

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


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


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

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

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

Хм. Предметная область это "складской учет", "управление производством", "контроль доступа". Идентифицируйте человека ссылкой на объект и расскажите, как это у вас получилось.
Re[10]: [Entity Framework]
От: sto Украина http://overstore.codeplex.com
Дата: 02.06.10 15:39
Оценка: 2 (1)
Здравствуйте, drol, Вы писали:

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


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


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

Надо различать две задачи: идентификацию самих объектов предметной области, и идентификацию экземпляров классов в ООП. Идентификация объектов предметной области — широкая и местами сложная тема, в которой надо плясать в основном от требований к приложению. Идентификация экземпляров — вещь очень простая: у каждого объекта в памяти есть адрес, в дотнете можно сравнивать объекты на ссылочное равенство (ReferenceEquals). Суррогатные ключи в базе данных — это аналог адреса объекта для базы — нужен для удобного обращения к определенной строке таблицы. Строго говоря, primary key необходим ОРМ-у внутри себя для обеспечения identity mapping, а также для сохранения/удаления объектов в/из базы. То свойство/поле с первичным ключом, которое содержится в объекте — это не более чем копия настоящего значения primary key, и для ОРМ его наличие не играет особой роли. Если бы это было не так, ОРМ не смог бы обеспечить правильность работы при изменении пользователем первичного ключа в объекте. То есть наличие в объекте свойства Customer.CustomerID — это опция для удобства и для обеспечения возможности обращаться к primary key объекта из LINQ2Entity.

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


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

Ну это правильно, но вынужденно, т.к. для URL необходим текстовый аналог уникальной ссылки на объект, и использовать для этого данные предметной области неудобно.
There is no such thing as the perfect design.
Re[13]: [Entity Framework]
От: Lloyd Россия  
Дата: 02.06.10 15:00
Оценка: 1 (1)
Здравствуйте, syomin, Вы писали:

S>>>поскольку составной первичный ключ нельзя использовать для описания внешних ключей.

G>>С чего ты это взял? Все можно.
S>Ссылку можно?

table_constraint (Transact-SQL)
Re[13]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 15:23
Оценка: 1 (1)
Здравствуйте, syomin, Вы писали:

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

S>>>В элементарном сферовакуумном примере для обеспечения идентичности объекта может использоваться связка из гражданства и номера паспорта человека. При этом сделать такой первичный ключ для соответствующей таблицы в БД конечно можно, но неудобно, поскольку составной первичный ключ нельзя использовать для описания внешних ключей.
G>>С чего ты это взял? Все можно.
S>Ссылку можно?
http://msdn.microsoft.com/en-us/library/ms174979.aspx

< table_constraint > ::=
[ CONSTRAINT constraint_name ] 
{ 
    { PRIMARY KEY | UNIQUE } 
        [ CLUSTERED | NONCLUSTERED ] 
                (column [ ASC | DESC ] [ ,...n ] ) 
        [ 
            WITH FILLFACTOR = fillfactor 
           |WITH ( <index_option> [ , ...n ] ) 
        ]
        [ ON { partition_scheme_name (partition_column_name)
            | filegroup | "default" } ] 
    | FOREIGN KEY 
                ( column [ ,...n ] ) 
        REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ]
        [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ] 
        [ NOT FOR REPLICATION ] 
    | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
}


Выделенное то что тебе нужно.

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

S>>>В описанном случае не нужен. Приложение уже есть и работает, теперь хочется добавить к нему базу данных, чтобы обеспечить персистентность.
G>>Как только объекты начинают "жить" дольше приложения сразу же стандартные средства ООП перестают работать.
S>Ну так и пусть ключи будут в storage model — я же не против. Другое дело, что не очень хочется их в conceptual model тащить...
Еще раз, не все сценарии бизнес-логики и даже UI возможны только на ссылках, потому что их время жизни гораздо меньше времени жизни "объектов".
То что ты написал программу так, что таких сценариев, нет никого не интересует, завтра у тебя появится такой сценарий и придется тащить везде ключи.
Поэтому производители ORM, несмотря на "чувство прекрасного", которое противоречит здравому смыслу, всетаки включают в модель ключи.

Кстати, как ты предполагаешь делать выборку по ключу, если у тебя их нет?
Re[4]: [Entity Framework]
От: syomin  
Дата: 02.06.10 09:25
Оценка: :)
Здравствуйте, HowardLovekraft, Вы писали:

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


S>>Первичный ключ используется базой данных для однозначной идентификации строки в таблице. S>Поскольку задача ORM'а состоит в том, чтобы изолировать объекты предметной области от базы 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[15]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 16:10
Оценка: +1
Здравствуйте, syomin, Вы писали:

G>>Кстати, как ты предполагаешь делать выборку по ключу, если у тебя их нет?


S>Чтобы сделать выборку по ключу, нужно этот ключ откуда-то взять. Варианты:

S>
S>Другими словами, мне не нужно делать поиск по ключу в явном виде. Вообще. В неявном виде (т.е. в SQL запросе) ключ фигурирует, но эту работу ТЕОРЕТИЧЕСКИ мог бы взять на себя EF.



Тогда тебе не нужна БД и ORM — сериализуй граф в файл и восстанавливай оттуда при запуске приложения. Иначе у тебя lazy load быстренько сам вытянет всю базу, а это все равно дольше выйдет.
[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[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[6]: [Entity Framework]
От: syomin  
Дата: 02.06.10 09:48
Оценка:
S>>Отдельным идентификатором? Нет, достаточно просто ссылки на объект.
HL>Хм. Предметная область это "складской учет", "управление производством", "контроль доступа". Идентифицируйте человека ссылкой на объект и расскажите, как это у вас получилось.

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


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


А причём тут цели-то ??? Разговор о задачах, а они именно те самые.
Re[6]: [Entity Framework]
От: syomin  
Дата: 02.06.10 14:18
Оценка:
D>Поехали по кругу: сие задача всех ORM'ов. То что длительное время люди не могли её внятно сформулировать, и в результате породили таких монстров как Hibernate и EF — это совсем другой вопрос.

Обратите внимание, что вопрос касается именно EF.
Re[7]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 14:23
Оценка:
Здравствуйте, syomin, Вы писали:

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


S>Обратите внимание, что вопрос касается именно EF.


Все известные мне ORMы мапят как минимум первичные ключи на объекты.
Re[11]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 14:28
Оценка:
Здравствуйте, syomin, Вы писали:

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

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

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

Это только соображения удобства.

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

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

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

S>>В описанном случае не нужен. Приложение уже есть и работает, теперь хочется добавить к нему базу данных, чтобы обеспечить персистентность.
G>Как только объекты начинают "жить" дольше приложения сразу же стандартные средства ООП перестают работать.
Ну так и пусть ключи будут в storage model — я же не против. Другое дело, что не очень хочется их в conceptual model тащить...
Re[11]: [Entity Framework]
От: drol  
Дата: 02.06.10 14:54
Оценка:
Здравствуйте, syomin, Вы писали:

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


Если у Вас более-менее сложная ООП-style модель данных, при разработке которой не учитывались вопросы сохраняемости, то добавить к такой конструкции "классический" persistence в БД => переписать почти всё что связано с оной моделью.

Вы точно уверены, что Вам именно БД нужна ? Для многих случаев ведь достаточно простейшей "залповой" сериализации всего графа объектов модели данных.
Re[14]: [Entity Framework]
От: syomin  
Дата: 02.06.10 15:48
Оценка:
G>Кстати, как ты предполагаешь делать выборку по ключу, если у тебя их нет?

Чтобы сделать выборку по ключу, нужно этот ключ откуда-то взять. Варианты:

Другими словами, мне не нужно делать поиск по ключу в явном виде. Вообще. В неявном виде (т.е. в SQL запросе) ключ фигурирует, но эту работу ТЕОРЕТИЧЕСКИ мог бы взять на себя EF.
Re[11]: [Entity Framework]
От: syomin  
Дата: 02.06.10 15:52
Оценка:
sto>Надо различать две задачи: идентификацию самих объектов предметной области, и идентификацию экземпляров классов в ООП. Идентификация объектов предметной области — широкая и местами сложная тема, в которой надо плясать в основном от требований к приложению. Идентификация экземпляров — вещь очень простая: у каждого объекта в памяти есть адрес, в дотнете можно сравнивать объекты на ссылочное равенство (ReferenceEquals). Суррогатные ключи в базе данных — это аналог адреса объекта для базы — нужен для удобного обращения к определенной строке таблицы. Строго говоря, primary key необходим ОРМ-у внутри себя для обеспечения identity mapping, а также для сохранения/удаления объектов в/из базы. То свойство/поле с первичным ключом, которое содержится в объекте — это не более чем копия настоящего значения primary key, и для ОРМ его наличие не играет особой роли. Если бы это было не так, ОРМ не смог бы обеспечить правильность работы при изменении пользователем первичного ключа в объекте. То есть наличие в объекте свойства Customer.CustomerID — это опция для удобства и для обеспечения возможности обращаться к primary key объекта из LINQ2Entity.

Спасибо за конструктивный ответ. Не подскажете, как можно сделать следующее:
Re[16]: [Entity Framework]
От: syomin  
Дата: 02.06.10 16:19
Оценка:
G>Тогда тебе не нужна БД и ORM — сериализуй граф в файл и восстанавливай оттуда при запуске приложения. Иначе у тебя lazy load быстренько сам вытянет всю базу, а это все равно дольше выйдет.

Возможный вариант, но хотелось бы использовать единое "хранилище" объектов для нескольких экземпляров приложения. Клиент-сервер, другими словами.
Re[17]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 16:28
Оценка:
Здравствуйте, syomin, Вы писали:

G>>Тогда тебе не нужна БД и ORM — сериализуй граф в файл и восстанавливай оттуда при запуске приложения. Иначе у тебя lazy load быстренько сам вытянет всю базу, а это все равно дольше выйдет.


S>Возможный вариант, но хотелось бы использовать единое "хранилище" объектов для нескольких экземпляров приложения. Клиент-сервер, другими словами.


Ну тогда тебе остается только свой ORM писать, покажи потом что получилось.
Re[18]: [Entity Framework]
От: syomin  
Дата: 02.06.10 16:34
Оценка:
G>Ну тогда тебе остается только свой ORM писать, покажи потом что получилось.
Проще победить чувство прекрасного...
Re[19]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 17:33
Оценка:
Здравствуйте, syomin, Вы писали:

G>>Ну тогда тебе остается только свой ORM писать, покажи потом что получилось.

S>Проще победить чувство прекрасного...

Тебе все равно придется это делать, твой подход к работе с данными положит приложение даже на небольших объемах.
Re[12]: [Entity Framework]
От: evi  
Дата: 02.06.10 19:07
Оценка:
Здравствуйте, syomin, Вы писали:
S>
Если использовать NHibernate, то CustomerId исчезнет. От Id избавляться не следует. Хотя бы потому, что в списке пользователю показывается облегчённый объект, а по клику открывается карточка полного объекта. По ссылкам объекты разные, Id — одинаковые.
Re: [Entity Framework]
От: henson Россия http://www.njt-rails.com
Дата: 02.06.10 19:39
Оценка:
Здравствуйте, syomin, Вы писали:

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


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


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


Я понимаю чего вы хотите добиться и для себя я выбрал BLToolkit вместо EF отчасти из аналогичных соображений.
В EF кое-что могло бы быть упрощено если бы EntityObject уже содержал некий общий Id который все равно нужен в каждом дочернем объекте.
Но для второго ID (CustomerId) проблема проистекает из реляционной модели данных вообще. Эта модель нуждается в ID, чтобы описать связи между объектами.
Иначе загрузка одного объекта потянет за собой всю базу данных, что совершенно ни к чему.

Посмотрите еще POCO objects и POCO proxy http://msdn.microsoft.com/en-us/library/bb738470.aspx

С другой стороны, если вам не нужно делать сложные выборке из базы, то проще использовать обычную сериализую объектов в XML или бинарный файл.
Re[2]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 02.06.10 20:45
Оценка:
Здравствуйте, henson, Вы писали:

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


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


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


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


H>Я понимаю чего вы хотите добиться и для себя я выбрал BLToolkit вместо EF отчасти из аналогичных соображений.


булкит — по большей части маппер, не умеет он identity map, поэтому ключики должны быть явными.

H>В EF кое-что могло бы быть упрощено если бы EntityObject уже содержал некий общий Id который все равно нужен в каждом дочернем объекте.

EntityKey?
Re[3]: [Entity Framework]
От: henson Россия http://www.njt-rails.com
Дата: 03.06.10 17:22
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


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


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


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


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


H>>Я понимаю чего вы хотите добиться и для себя я выбрал BLToolkit вместо EF отчасти из аналогичных соображений.

G>
G>булкит — по большей части маппер, не умеет он identity map, поэтому ключики должны быть явными.

Соображение было такое, что если EF этого не делает, то лучше использовать BLToolkit, который все остальное намного легче и быстрей, даже если автоматического identity mapping там тоже нет

H>>В EF кое-что могло бы быть упрощено если бы EntityObject уже содержал некий общий Id который все равно нужен в каждом дочернем объекте.

G>EntityKey?

EntityKey все-таки не поле в базе данных, а объект хранящий ссылку на ключевое поле, т.е. какой-то дополнительный Id ВСЕГДА нужен
Re[4]: [Entity Framework]
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 03.06.10 19:32
Оценка:
Здравствуйте, henson, Вы писали:

H>>>В EF кое-что могло бы быть упрощено если бы EntityObject уже содержал некий общий Id который все равно нужен в каждом дочернем объекте.

G>>EntityKey?

H>EntityKey все-таки не поле в базе данных, а объект хранящий ссылку на ключевое поле, т.е. какой-то дополнительный Id ВСЕГДА нужен

Неверно. http://msdn.microsoft.com/ru-ru/library/system.data.entitykey(VS.90).aspx
Re[5]: [Entity Framework]
От: henson Россия http://www.njt-rails.com
Дата: 03.06.10 20:31
Оценка:
Здравствуйте, gandjustas, Вы писали:

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


H>>>>В EF кое-что могло бы быть упрощено если бы EntityObject уже содержал некий общий Id который все равно нужен в каждом дочернем объекте.

G>>>EntityKey?

H>>EntityKey все-таки не поле в базе данных, а объект хранящий ссылку на ключевое поле, т.е. какой-то дополнительный Id ВСЕГДА нужен

G>Неверно. http://msdn.microsoft.com/ru-ru/library/system.data.entitykey(VS.90).aspx

Что именно неверно? Как использовать EntityKey без внешнего ID ?
Re[3]: [Entity Framework]
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.06.10 11:32
Оценка:
Здравствуйте, syomin, Вы писали:

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

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

Тогда лучше начать с исправления этого самого чувства.

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

Данные есть данные. И в объекты ты их кладешь только потому, что так удобнее получить доступ к этим самым данных в твоем любимом языке.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: [Entity Framework]
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.06.10 11:40
Оценка:
Здравствуйте, syomin, Вы писали:

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


Не читайте Фаулера перед обедом.

"изолировать объекты предметной области от базы данных" — это задача Object Persistence Framework-ов, а не ORM. Задача ORM же намного проще — преобразовать реляционные данные (записи из таблиц) в списки объектов, тем самым упростив их обработку в ООЯ.

Так вот, Persistence Framework-и приводят к неоправданному оверхэду, при этом не давая реального повышения уровня абстрации.

S>то перечисленных выше полей быть не должно — достаточно просто ссылок. Думаю, технически это возможно. Другое дело, возможно ли это в EF.


Если тебе нужен Persistence Framework, то лучше выбрать Hibernate. Только потом не надо задавать вопрос "почему моё приложение так тормозит?".

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

S>Не конструктивно.

Последнее как раз конструктивно. Первое, конечно, перебор. Но вот доверять всему чему пишут в ООП-книгах нужно с оглядкой. ООП не панацея. Где-то он отлично ложится на задачу. Где-то он просто вреден или менее удобен.

Для обработки данных хранящихся в СУБД лучше подходит функциональный подход, а не ООП.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: [Entity Framework]
От: VladD2 Российская Империя www.nemerle.org
Дата: 08.06.10 11:45
Оценка:
Здравствуйте, syomin, Вы писали:

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

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

Это называется "составной первичный ключ".

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


А зачем пользователю то показывать? Скрывай его. Но в той же форме его держать надо, чтобы потом было по чему обновлять данные. (Хотя я не раз видел как люди запоминали свои номера и потом быстро по ним идентифицировались.)

Смотри какая фигня получается. Скрыв идентификатор в объекте и пытаясь идентифицировать что-то самим экземпляром объекта ты будешь вынужден сделать объект уникальным. Это резко усложняет работу с ним. Ты вынужден гарантировать, что данные в этом объекте синхронны данным в БД и то, что объект один. Это же означает, что такой же объект в другом процессе уже заводить чревато.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[19]: [Entity Framework]
От: _FRED_ Черногория
Дата: 08.06.10 11:46
Оценка:
Здравствуйте, syomin, Вы писали:

G>>Ну тогда тебе остается только свой ORM писать, покажи потом что получилось.

S>Проще победить чувство прекрасного...

Если действительно достаточно загрузить сразу в память все данные, покрутить их там и сбросить на диск, то вам ни ОРМ ни БД даром не нудны: созраняйте в бинарник или в хмл на диск. Если нужна БД, то такой "ОРМ" делается за пол-дня/день, что совсем не дорого На крайняк можно в той же БД хранить граф в хмл. В таком случае просто EF — это молоток в ситуации, когда нужны пасатижы (здесь).

А вот как только [если] вам понадобится не "целый граф", а постепенное вытягиание сущностей, сохранение с обновлением, а не перезаписыванием, то иметь в какой-либо форме ижентификатор в объекте, с которым происходит работа пользователя придётся.
Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.