Эквивалент метода Load для NHibernate IStatelessSession - PullRequest
3 голосов
/ 21 марта 2012

Я использую NHibernate для массовой вставки строк в мою базу данных. Из-за объема данных, которые я вставляю, я использую IStatelessSession вместо ISession. Вставляемые объекты используют присвоенные идентификаторы (т. Е. Не генерируются hilo или guids - уникальные идентификаторы назначаются объектам).

Моя проблема в том, что у меня есть объект (скажем, Foo), который имеет ссылку "многие-к-одному" на другой объект (скажем, Bar). Сначала я вставляю все объекты Bar, и это не проблема.

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

Сейчас самое время показать простой пример:

public class Foo {
    // Unique identifier (assigned)
    public virtual int Id { get; set; }

    // Many-to-one reference to a Bar object
    public virtual Bar Bar { get; set; }
}

public class Bar {
    // Unique identifier (assigned)
    public virtual int Id { get; set; }
}

Допустим, я хочу создать новый Foo объект с Id из (скажем) 1234, который ссылается на Bar объект с Id (скажем) 4567. Я знаю, что уже есть Bar объект с этим идентификатором, потому что ранее я добавил все Bar объекты.

Как мне добавить объект Foo без необходимости повторного извлечения объекта Bar из базы данных?

Ответы [ 4 ]

4 голосов
/ 21 марта 2012

Странно, что иногда, если вы нашли время, чтобы сформулировать свой вопрос, вы вскоре поймете ответ.

Что вы делаете, это создаете фиктивный объект, у которого есть Id и больше ничего не установлено.

ШАГ 1: Вставить объект Bar

using (var session = SessionFactory.OpenStatelessSession())
{
    using (var tx = session.BeginTransaction())
    {
        var bar = new Bar
        {
            Id = 1234,
            // and populate all of the other
            // properties that you would put here
        };
        session.Insert(bar);
        tx.Commit();
    }
}

ШАГ 2: Вставить объект Foo с фиктивным объектом Bar

using (var session = SessionFactory.OpenStatelessSession())
{
    using (var tx = session.BeginTransaction())
    {
        var foo = new Foo
        {
            Id = 4567,
            // dummy Bar object that has an Id and nothing else
            Bar = new Bar {Id = 1234}
        };
        session.Insert(foo);
        tx.Commit();
    }
}

Но если у кого-то есть лучший способ (например, не требующий создания большого количества фиктивных объектов), я был бы признателен за совет.

2 голосов
/ 21 марта 2012

Сохраните объекты Bar в Dictionary<int, Bar> после их вставки и присвойте ссылку правильному объекту Bar:

var foo = new Foo();
foo.Bar = bars[1234];
session.Save(foo); // there is no session.Insert method

Ваше решение также работает, но для общего Bar.Id требуется общедоступный установщик1005 *

0 голосов
/ 21 марта 2012

Это НЕ совершает поездку в базу данных и является способом заполнения внешнего ключа без необходимости загрузки сущности.

var foo = new Foo
{
  Id = 4567,
  Bar = new Session.Get<Bar>(1234)
};

Игнорирование.

0 голосов
/ 21 марта 2012

Вы можете использовать session.Get (id), если у сеанса есть сущности Бара, он возвращает прокси, и вы создадите объект Foo по ссылке на прокси без какого-либо обращения к базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...