NHibernate: как включить ленивую загрузку при сопоставлении "один к одному"

Индивидуальные отношения внутри nhibernate могут быть lazyloaded либо "false", либо "proxy". Мне было интересно, знает ли кто-нибудь способ сделать ленивое сопоставление "один-к-одному".

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

Спасибо заранее!

Ответы

Ответ 1

Ленивая загрузка одного к одному не поддерживается, если ассоциация не является обязательной. См. здесь для обоснования.

Это сводится к тому, что для того, чтобы решить, существует ли другая сторона отношения (N), Hibernate должен перейти в базу данных. Поскольку вы уже удалили базу данных, вы можете загрузить полный объект.

Хотя бывают случаи, когда удары по БД просто для того, чтобы увидеть, существует ли связанный объект без реальной загрузки объекта, имеет смысл (если связанный объект очень "тяжелый" ), он в настоящее время не поддерживается в NHibernate.

Ответ 2

Насколько я знаю, нет ленивого способа ленивой загрузки "один к одному". Надеюсь, я ошибаюсь, но в прошлый раз я проверил, что это так.

Ответ 3

Есть мысли. Он подробно описал здесь:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernateTest" namespace="NHibernateTest">
  <class name="Person" >
    <id name="PersonID" type="Int32">
      <generator class="identity" />
    </id>
    <property name="LastName" type="String" length="50" />
    <property name="FirstName" type="String" length="50" />
    <many-to-one name="Photo" class="PersonPhoto" />
  </class>

  <class name="PersonPhoto">
    <id name="PersonID" type="Int32">
      <generator class="foreign">
        <param name="property">Owner</param>
      </generator>
    </id>
    <property name="Photo" type="BinaryBlob" />
    <one-to-one name="Owner" class="Person" constrained="true" />
  </class>
</hibernate-mapping> 

Ответ 4

Я попробовал пример, использованный Артем Тихомировым выше. Я продолжал ошибаться, что столбец "Фото" не существует. Посмотрев этот, я понял, что сопоставление было немного. Когда я изменил сопоставление "много-к-одному", чтобы указать имя столбца следующим образом:

много-к-одному name= "Фото" column = "PersonID" class= "PersonPhoto" unique = "true"

Я заработал. Надеюсь, это поможет кому-то: o)

Ответ 5

Прочитав ответы здесь, мне удалось заставить его работать. Я просто собираюсь добавить этот пример, потому что я использую отношение "один к одному" с Constrained = False и потому что это сопоставление по примеру кода

Два класса:

public class Pedido:BaseModel
{
    public virtual BuscaBase Busca { get; set; }
}

public class BuscaBase : BaseModel
    {       
        public virtual Pedido Pedido { get; set; }
    }

Отображения:

public class PedidoMap : ClassMapping<Pedido>
{
    public PedidoMap()
    {
         Id(x => x.Id, x => x.Generator(Generators.Identity));            

         ManyToOne(x => x.Busca, m => 
         { 
             m.Cascade(Cascade.DeleteOrphans);
             m.NotNullable(true); m.Unique(true);
             m.Class(typeof(BuscaBase));
         });    
    }
}

public class BuscaBaseMap : ClassMapping<BuscaBase>
{
    public BuscaBaseMap()
    {            
        Id(x => x.Id, x => x.Generator(Generators.Sequence, g => g.Params(new { sequence = "buscaefetuada_id_seq" })));

        OneToOne(x => x.Pedido, m =>
        {
            m.Lazy(LazyRelation.NoProxy);
            m.Constrained(false);
            m.Cascade(Cascade.None);
            m.Class(typeof(Pedido));
        });            
    }
}

Примечание: я использовал для однозначного отображения m.PropertyReference(typeof(Pedido).GetProperty("Busca")); но это не работает для ленивой загрузки. Вы должны указать отношение, используя класс