2016-03-06 2 views
0

У меня есть две модели, DerbySpawn и DerbyArenaОдин ко многим в NHibernate

DerbyArena.cs

public class DerbyArena 
{ 
     public DerbyArena() 
     { 
      DerbySpawns = new List<DerbySpawn>(); 
     } 
     public virtual int Id { get; set; } 
     public virtual string Name { get; set; } 
     public virtual short MaxPlayers { get; set; } 
     public virtual short MinPlayers { get; set; } 
     public virtual short Interior { get; set; } 
     public virtual short Model { get; set; } 
     public virtual float MinZ { get; set; } 
     public virtual IList<DerbySpawn> DerbySpawns { get; set; } 
} 

DerbySpawn.cs

public class DerbySpawn 
{ 
    public virtual int SpawnId { get; set; } 
    public virtual float SpawnX { get; set; } 
    public virtual float SpawnY { get; set; } 
    public virtual float SpawnZ { get; set; } 
    public virtual float SpawnA { get; set; } 
    public virtual DerbyArena DerbyArena { get; set; } 
} 

И мое отображение

DerbyArenaMap

public class DerbyArenaMap : ClassMap<DerbyArena> 
{ 
      public DerbyArenaMap() 
      { 
       Id(x => x.Id); 
       Map(x => x.Interior); 
       Map(x => x.MaxPlayers); 
       Map(x => x.MinPlayers); 
       Map(x => x.Model); 
       Map(x => x.Name); 
       Map(x => x.MinZ); 
       HasMany<DerbySpawn>(x => x.DerbySpawns) 
        .Inverse() 
        .AsBag(); 
       Table("DerbyArens"); 


      } 
} 

DerbySpawnMap

public class DerbySpawnMap : ClassMap<DerbySpawn> 
{ 
     public DerbySpawnMap() 
     { 
      Id(x => x.SpawnId); 
      Map(x => x.SpawnX); 
      Map(x => x.SpawnY); 
      Map(x => x.SpawnZ); 
      Map(x => x.SpawnA); 
      References(x => x.DerbyArena); 
      Table("DerbySpawns"); 

     } 
    } 

В DerbyArens столбце Идентификатор первичного ключа, Auto Increment

В DerbySpawns колонке SpawnId является первичный ключ, Auto Increment и столбец DerbyArena является внешний ключ Связь со столом DerbyArens, столбец Id

Я выбираю случайную арену с помощью этого кода:

using (ISession session = DbSession.OpenSession()) 
{ 
     arena = (from x in session.Query<DerbyArena>() orderby Guid.NewGuid() select x).First(); 
} 

Но когда я использую

Console.Write(arena.DerbySpawns[y].SpawnX + " " + arena.DerbySpawns[y].SpawnY + " " + arena.DerbySpawns[y].SpawnZ + " " + arena.DerbySpawns[y].SpawnA); 

я получаю исключение

NHibernate.LazyInitializationException: Инициализация [SSS.Models.DerbyArena # 1] - не удалось лениво инициализировать сборник роли: SSS.Models.DerbyArena.DerbySpawns, сеанс или сеанс не закрыты

DbSession.cs

public static class DbSession 
{ 
    private static ISessionFactory _sessionFactory; 
    public static ISessionFactory Factory 
    { 
     get { return _sessionFactory ?? (_sessionFactory = CreateSessionFactory()); } 
    } 
    public static ISession OpenSession() 
    { 
     return Factory.OpenSession(); 
    } 

    private static ISessionFactory CreateSessionFactory() 
    { 
     return Fluently.Configure() 
      .Database(
       MySQLConfiguration.Standard 
        .ConnectionString("connectionstring(thiswork)") 
      //Your connectionstring goes here. 
      ) 
      .Mappings(m => 
       m.FluentMappings.AddFromAssemblyOf<DbMappings>()) 
      .ExposeConfiguration(TreatConfiguration) 
      .BuildSessionFactory(); 
    } 


    private static void TreatConfiguration(Configuration configuration) 
    { 
     var update = new SchemaUpdate(configuration); 
     update.Execute(false, true); 
    } 

} 

ответ

0

Скорее всего, вы обращаетесь к DerbySpawns за пределами using (ISession ..., в то время как отложенная загрузка включена на него.

Поскольку сеанс размещен using, ленивая загрузка не может произойти.

Вы должны обеспечить отсутствие ленивой загрузки после закрытия сессии.

  1. Сделайте всю свою единицу работы внутри using (ISession ....
  2. Или достаньте ваши зависимости внутри using (ISession ...:
    • Использование жадная загрузка (.FetchMany по Вашему запросу). Остерегайтесь, в сочетании с вашим «случайным сортировкой», это, скорее всего, приведет вас к this bug (с пометкой EF, но я уверен, что NH тоже будет), заставляя вас использовать more complex 'random sort'.
    • Или запустите ленивую загрузку, обратившись к объекту. Если это всего лишь «фиктивный» доступ, это будет довольно грязно ...
    • Или принудительная выборка в этой коллекции в сопоставлениях (удары всех DerbyArena загрузок, также очень вероятно приведет к ранее упомянутой ошибке).
Смежные вопросы