powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
10 сообщений из 10, страница 1 из 1
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36413458
Abbey Road
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте.
Нужен совет

Имеем:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
interface IFoo
{
   Guid Id {get;set;}
   string Caption {get;}
}

class Foo1 : IFoo
{ 
   Guid Id {get;set;}
   string Name1 {get;set;}
   string Caption {get {return Name1;}}
}

class Foo2 : IFoo
{
   Guid Id {get;set;}
   string Name2 {get;set;}
   string Name3 {get;set;}
   string Caption {get {return Name2+Name3;}}
}
Маппинг задаю при помощи FluentNHibernate
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
class FooMap : ClassMap<IFoo>
{
   Table("FooMain");
   Id(x=>x.Id);
}
class Foo1Map : SubClassMap<Foo1>
{
   Map(x=>x.Name1);
   Map(x=>x.Caption).None.Filter("Name1");
}
class Foo2Map : SubClassMap<Foo2>
{
   Map(x=>x.Name2);
   Map(x=>x.Name3);
   Map(x=>x.Caption).None.Filter("Name2 + Name3");
}

Теперь, когда делаю выборку вида
Код: plaintext
1.
repository.Linq<IFoo>().ToList();
Получаю нужное поведение - коллекцию IFoo с обоими классами Foo1, Foo2.
Запрос с условием по любому отдельному классу тоже отрабатывает как надо:
Код: plaintext
1.
repository.Linq<Foo2>().Where(x=>x.Caption.Contains("test")).ToList();
Но когда условие применяется к выборке по интерфейсу:
Код: plaintext
1.
repository.Linq<IFoo>().Where(x=>x.Caption.Contains("test")).ToList();
Формируется ошибочный sql (примерно):
select t1.id, t2.name1, t3.name2, t3.name3 , ...
from t1 join ... t2 ... join t3 ...
where ( t2.name2 + t2.name3 ) like '%test%'
т.е. не отрабатывается полиморфное поведение (при этом по отдельности в выборке по каждому классу отрабатывается и sql формируется правильно)
Кто-нибудь знает элегантное решение этой проблемы? Может быть я где-то-что-то не правильно указал ? (кстати очень смущает необходимость дублировать логику в маппинг-классах)

PS. Гугл подсказал следующие решения:
1. Хранить вычисляемое значение в отдельном private поле и соответственно писать его в базу в родительскую таблицу
2. Выбирать все, потом обработать linq to objects
3. Перестраивать expression tree разнообразными способами.
PPS. Может это просто глюк NHibernate.Linq, а обычный NHibernate справляется с такой ситуацией?

Спасибо.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36413678
Курочка Ряба
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Abbey RoadМожет это просто глюк NHibernate.Linq, а обычный NHibernate справляется с такой ситуацией?
Я думаю да.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36413700
Abbey Road
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще кто-нибудь такую схему реализовывал?
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36413712
Курочка Ряба
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Abbey RoadА вообще кто-нибудь такую схему реализовывал?
Что мне не нравится в Вашей схеме, это то, что Вы закладываете под свои Entity единый интерфейс IFoo, который требует реализовать в наследуемых классах 2 члена. Это не всегда прокатит. Для решений с 10-ю табличками, да - эта универсализация сработает. Но на реальных проектах далеко не все Entity должны плясать по таким правилам. Гораздо лучше пометить свои Entity каким-нить базовым классом (для начала пустым) или пустым интерфейсом (для дальнейших обобщений).
Во-вторых, как-то тестил я линк ту хибер. Слишком сыроват и малофункционален. Покрывает 10% возможностей классических хибер-запросов.
В-третьих, как-то выкладывал вот тут вариант репозитория под хиб, гляньте, может понравится, почитайте топик.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36413735
Abbey Road
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторвот тут вариант
Спасибо, ознакомлюсь.

Задача стоит в объединении слегка разнородных классов (они уже существуют и могут только дорабатываться) для определенной задачи. Поэтому вводится интерфейс IFoo с требованиями от задачи, для него создается отдельная таблица. А классы дорабатываются с целью реализации интерфейса.
В остальном проекте, средств NH.Linq вполне хватает, поэтому и хочется реализовать всё единообразно.
Ладно, сегодня посмотрю как nh.linq строит expression tree для таких запросов. И попробую заодно реализовать это на чистом nhibernate.
Спасибо.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36413737
Курочка Ряба
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Abbey RoadПоэтому вводится интерфейс IFoo с требованиями от задачи
Вы просто заранее ставите себе палки в колёса :)

Abbey RoadИ попробую заодно реализовать это на чистом nhibernate.
Спасибо.
Ок, отпиш и тесь о результатах.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36414821
Abbey Road
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробовал на чистом NHibernate без fluent'a, и linq.
Итог: ошибка самого NHibernate или я просто не умею правильно настроить

Он условие where неправильно формирует, приписывая фильтр не к тому классу-таблице.

Запрос:
IQuery cq = sx.CreateQuery("from IClient c where c.Caption = :name");

Результат:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select 
iclient0_.Id as Id0_, 
iclient0_1_.CompanyName as CompanyN2_1_, 
iclient0_2_.Surname as Surname2_, 
iclient0_2_.Firstname as Firstname2_, 
iclient0_1_.CompanyName as formula0_, 
iclient0_2_.Surname + ' ' + iclient0_2_.Firstname as formula1_, 
iclient0_.ClientType as ClientType0_ 

from Client iclient0_ 
left outer join Company iclient0_1_ on iclient0_.Id=iclient0_1_.Id 
left outer join Human iclient0_2_ on iclient0_.Id=iclient0_2_.Id 

where iclient0_1_.Surname + ' ' + iclient0_1_.Firstname=@p0
-- А нужно 
-- where (iclient0_2_.Surname + ' ' + iclient0_2_.Firstname=@p0) or (iclient0_1_.CompanyName=@p0)


Классы

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
    public interface IClient
    {
        Guid Id { get; set; }
        string Caption { get; set; }
    }

    public class Human : IClient
    {
        public virtual Guid Id { get; set; }

        public virtual string Caption { get { return Surname + " " + Firstname; } set { } }

        public virtual string Surname { get; set; }
        public virtual string Firstname { get; set; }
    }

    public class Company : IClient
    {
        public virtual Guid Id { get; set; }

        public virtual string Caption { get { return CompanyName; } set { } }

        public virtual string CompanyName { get; set; }
    }


Маппинги

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="testSubclassWhere"
                   namespace="testSubclassWhere.Domain">
  <class name="IClient"
         abstract="true"
         table="Client">
    <id name="Id" column="Id">
      <generator class="guid"/>
    </id>
    <discriminator column="ClientType" type="string"/>
    <subclass name="Company" discriminator-value="C">
      <join table="Company">
        <key column="Id"/>
        <property name="CompanyName"/>
        <property name="Caption" formula="CompanyName"/>
      </join>
    </subclass>
    <subclass name="Human" discriminator-value="H">
      <join table="Human">
        <key column="Id"/>
        <property name="Surname"/>
        <property name="Firstname"/>
        <property name="Caption" formula="Surname + ' ' + Firstname"/>
      </join>
    </subclass>
  </class>
</hibernate-mapping>


Буду разбираться дальше.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36415342
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Abbey Road
Код: plaintext
1.
-- А нужно 
where (iclient0_2_.Surname + ' ' + iclient0_2_.Firstname=@p0) >>or<< (iclient0_1_.CompanyName=@p0)

Какой-то глупый запрос, Вам не кажется?

Сами подумайте, Surname + Firstname || CompanyName : выглядит по-меньшей мере стратнно.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36415386
Dmitdd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
МСУ
Какой-то глупый запрос, Вам не кажется?

Сами подумайте, Surname + Firstname || CompanyName : выглядит по-меньшей мере стратнно.
Почему бы и нет. Есть клиент физ лицо и юрлицо, по названию клиента хочется произвести поиск.
Как решение - создать вьюшку и замапить отдельный класс на нее. В чем преимущество - во вьюшке будет колонка Caption, по которой можно создать индекс.
...
Рейтинг: 0 / 0
Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
    #36416983
Abbey Road
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУКакой-то глупый запрос, Вам не кажется?
Сами подумайте, Surname + Firstname || CompanyName : выглядит по-меньшей мере стратнно.
Немного не понял. Развернете свою мысль?
Я веду речь о вычисляемых полях, которые рассчитывают свое значение на основании свойств класса. И, в данный момент, не важно что именно они рассчитывают. Мне нужна выборка по этому полученному значению. А будут это IFoo, IClient, или еще какие хитрые классы реализующие разные стратегии расчета процентных ставок - в тестовом примере это не принципиально.

Dmitdd,
вариант с view тоже приемлем, но в этом случае нужно учитывать, что нарушается инкапсуляция.
В итоге, выбирая наиболее оптимальный для себя вариант и учитывая, что:
я не хочу нарушать инкапсуляцию (выносить логику в БД, маппинг классы...)

нужен именно быстрый поиск средствами БД (where column = value), используя NHibernate (session.Linq().Where(x=>x.Column == value)
решил рассчитывать это самое значение в приватную переменную при изменении зависимых свойств класса и мапить ее на родительскую таблицу. Лишнее место на диске в данной задаче не сильно беспокоит, целостность связанных данных обеспечат транзакции.
Не очень нравится это решение, поэтому буду рад комментариям и предложениям.

Спасибо.
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Вопрос по вычисляемым свойствам, наследованию и NHibernate.Linq
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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