Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate: маппинг 2 классов на 1 таблицу / 7 сообщений из 7, страница 1 из 1
24.07.2009, 07:21
    #36106867
AlexMAS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
Здравствуйте!
Недавно начал работать с NHibernate и натолкнулся на одну особенность.

Допустим, у меня есть таблица:

Код: plaintext
create table MyTest (Id int identity, Field1 nvarchar( 50 ), Field2 nvarchar( 50 ))

Два класса (один наследник другого):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
public class BaseClass
{
   public virtual object Id { get; set; }
   public virtual string Field1 { get; set; }
}
public class NestedClass : BaseClass
{
   public virtual string Field2 { get; set; }
}

А также mapping:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
<!-- BaseClass -->
<class name="BaseClass" table="[dbo].[MyTest]">
   <id name="Id" column="Id" type="Int32"><generator class="native"/></id>
   <property name="Field1" column="Field1" type="string"/>
</class>
<!-- NestedClass -->
<class name="NestedClass" table="[dbo].[MyTest]">
   <id name="Id" column="Id" type="Int32"><generator class="native"/></id>
   <property name="Field1" column="Field1" type="string"/>
   <property name="Field2" column="Field2" type="string"/>
</class>

Таким образом, при выполнении следующего кода:

Код: plaintext
1.
2.
ISession session;
var listBaseClass = session.CreateCriteria(typeof(BaseClass)).List<BaseClass>();
var listNestedClass = session.CreateCriteria(typeof(NestedClass)).List<NestedClass>();

В базу уходят такие запросы:

Код: plaintext
1.
2.
3.
4.
--Load BaseClass
select Id, Field1, Field2 from MyTest
select Id, Field1 from MyTest
--Load NestedClass:
select Id, Field1, Field2 from MyTest

Однако я бы хотел добиться такого эффекта, чтобы при загрузке списка BaseClass был лишь один запрос:

Код: plaintext
1.
2.
3.
--Load BaseClass
select Id, Field1 from MyTest
--Load NestedClass:
select Id, Field1, Field2 from MyTest

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

Заранее спасибо.

P.s. Суть в том, чтобы не загружать лишние данные из базы. Lazy использовать нельзя, т.к. в дальнейшем сущность будет передаваться по сети (WCF).
...
Рейтинг: 0 / 0
24.07.2009, 13:28
    #36107648
Нахлобуч
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
...
Рейтинг: 0 / 0
24.07.2009, 13:39
    #36107675
AlexMAS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
Нахлобуч Сюда

С возможностями Inheritance Mapping NHibernat'а я знаком. Вопрос то в другом. Почему при выборке базового класса он делает два селекта (и соответственно возвращает в 2 раза больше записей)?
...
Рейтинг: 0 / 0
26.07.2009, 16:26
    #36109617
D129
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
AlexMASНахлобуч Сюда

С возможностями Inheritance Mapping NHibernat'а я знаком. Вопрос то в другом. Почему при выборке базового класса он делает два селекта (и соответственно возвращает в 2 раза больше записей)?
А что было сохранено - только обьект базового класса?
Если нет - то сохранен производный, а сейчас вы хотите его производную часть отбросить (если я правильно понял...)?
...
Рейтинг: 0 / 0
27.07.2009, 07:02
    #36109943
AlexMAS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
D129,

Думаю, вы правильно поняли.
Допустим, вышеуказанная таблица содержит следующие записи (сохранен производный класс):

Код: plaintext
1.
2.
3.
4.
Id | Field1 | Field2
--------------------
1  | 11     | 12
2  | 21     | 22
3  | 31     | 32

При выполнении:
Код: plaintext
var listBaseClass = session.CreateCriteria(typeof(BaseClass)).List<BaseClass>();
должен генрироваться запрос:
Код: plaintext
select Id, Field1 from MyTest
и возвращаться список объектов только BaseClass (данные из колонки Field2 не выбираются).

А при выполнении:
Код: plaintext
var listNestedClass = session.CreateCriteria(typeof(NestedClass)).List<NestedClass>();
должен генерироваться запрос:
Код: plaintext
select Id, Field1, Field2 from MyTest
и возвращаться список объектов NestedClass (выбираются все данные).
...
Рейтинг: 0 / 0
27.07.2009, 15:00
    #36111142
D129
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
AlexMAS,

Ну тогда я вижу два пути
- сделать кастинг к базовому обьекту для всего списка (сейчас это просто) - и игнорировать "перерасход" памяти (ее сейчас везде много), кроме того - если информация есть, есть вероятность что она понадобится - остается возможность кастинга обратно.
то есть, не решать проблему. :) (так как по моему мнению, лишние (ну сколько? 50? 500? байт на обьект - это уже мелочь)

- Вот вы пишите "генерируется запрос" - и не такой как вы хотите. Значит, надо его генерировать самостоятельно. Пишите свой ДАЛ. Пусть он возвращает только то, что вы хотите вернуть. То есть - класс дата аксессора, который будет брать из базы только данные базового типа, и возвращать только базовый тип, игнорируя присутствие полей производного.
...
Рейтинг: 0 / 0
27.07.2009, 19:03
    #36111901
AlexMAS
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
NHibernate: маппинг 2 классов на 1 таблицу
Спасибо за ответы.
В моем случае лучше всего подошло решение с собственным DAL, поскольку получил значительный выигрыш во времени выборки.
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / NHibernate: маппинг 2 классов на 1 таблицу / 7 сообщений из 7, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]