Nhibernate: остановить его от присоединения к таблице, которая не нужна - PullRequest
1 голос
/ 08 июня 2010

У меня есть две таблицы (tbArea, tbPost), которые относятся к следующим классам.

class Area
{
    int ID
    string Name
    ...
}

class Post
{
    int ID
    string Title
    Area Area
    ...
}

Эти два класса отображаются вместе с Fluent Nhibernate. Ниже приведено сопоставление постов.

public class PostMapping : ClassMap<Post>
{
    public PostMapping()
    {
        Cache.NonStrictReadWrite();

        this.Table("tbPost");

        Id(x => x.ID)
            .Column("PostID")
            .GeneratedBy
            .Identity();

        References(x => x.Area)
            .ForeignKey("AreaID")
            .Column("AreaID");
        ...
    }
}

Каждый раз, когда я выполняю запрос к таблице сообщений "где AreaID = 1 (любой AreaId)", nhibernate присоединяется к таблице областей.

(Что генерирует Nhibernate для запроса)

SELECT
    post fields
,   area fields (automatically added)
FROM tbPost p
LEFT JOIN tbArea a on 
        p.areaid = a.areaid
where
    p.areaid = 1

Я попытался установить для Area значение LazyLoad, Fetch.Select, ReadOnly и любые другие параметры для ссылки, но он всегда будет присоединяться к Area.

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

Какие конфигурации мне нужно изменить или сопоставить, чтобы область оставалась связанной с публикацией в моих объектах, но не запрашивала ее при фильтрации по AreaID?

Ответы [ 3 ]

2 голосов
/ 10 июня 2010

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

http://codeofrob.com/archive/2009/10/22/why-linq2nhibernate-isnt-ready-for-production-use.aspx

Я предложил два решения.Хотя использование CreateCriteria действительно создавало правильные запросы, оно не работало с тем, как я реализую свой уровень доступа.Мне все еще нужно было выполнить, где передавались операторы на основе Expressions<Func<T,bool>> операторов. Два найденных решения:

  1. Используйте эту библиотеку для создания критериев из лямбда-операторов.

    http://code.google.com/p/nhlambdaextensions/

    Лямбда-расширения не работают так, как я надеялся, но могут работать для других с такой же проблемой.

  2. ВВ конце концов, лучшим решением для использования Linq с моими запросами было загрузить и собрать версию для разработки Nhibernate 3. Новый поставщик Linq в NH3 работает отлично, и запросы выглядели так, как я ожидал.

    http://sourceforge.net/projects/nhibernate/develop

1 голос
/ 08 июня 2010

Что такое код запроса?Это должно работать.

s.CreateCriteria<Post>()
    .Add(Restrictions.Eq("Area.ID", 1))
    .List<Post>();

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

0 голосов
/ 10 июня 2010

Не знаком с NHibernate, но насколько я знаю, он похож на LINQ.

Например, у меня есть 2 таблицы:

Клиент Заказ

1 клиент имеет 0-много заказов.

Обновление заказа через LINQ обновит прикрепленного клиента. В моем случае это было добавление дубликата клиента в таблицу.

Мне пришлось реализовать метод Detach() для класса заказов.

псевдокод:

public void Detach()
{
   this._ReferenceToCustomer = emptyCustomerReference;
}

Идея состоит в том, чтобы отделить клиента от заказа. Это то, что вы ищете?

...