NHibernate 一对多
One to many in NHibernate
我有两个模型,DerbySpawn 和 DerbyArena
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; }
}
还有我的映射
德比竞技场地图
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 中,列 Id 为主键,自增
在 DerbySpawns 列 SpawnId 是主键,自动递增,列 DerbyArena 是外键 与 table DerbyArens 的关系,列 Id
我select通过这个代码随机竞技场:
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: Initializing[SSS.Models.DerbyArena#1]-failed to lazily initialize a collection of role: SSS.Models.DerbyArena.DerbySpawns, no session or session was closed
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);
}
}
很可能您在 using (ISession ...
之外访问 DerbySpawns
,而在其上启用了延迟加载。
由于session被using
释放,延迟加载不会发生
您必须确保会话关闭后不会发生延迟加载。
- 在
using (ISession ...
内完成整个工作单元。
- 或在
using (ISession ...
中获取您的依赖项:
- 使用预先加载(
.FetchMany
在您的查询中)。当心,结合您的 'random sort',这很可能会导致您 this bug (tagged as EF but I am quite confident NH would have it too), forcing you to use a more complex 'random sort'.
- 或者通过访问属性来触发延迟加载。如果这只是一个 'dummy' 访问,那就太脏了...
- 或者在映射中强制获取此集合(影响所有
DerbyArena
加载,也很可能导致前面提到的错误)。
我有两个模型,DerbySpawn 和 DerbyArena
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; }
}
还有我的映射
德比竞技场地图
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 中,列 Id 为主键,自增
在 DerbySpawns 列 SpawnId 是主键,自动递增,列 DerbyArena 是外键 与 table DerbyArens 的关系,列 Id
我select通过这个代码随机竞技场:
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: Initializing[SSS.Models.DerbyArena#1]-failed to lazily initialize a collection of role: SSS.Models.DerbyArena.DerbySpawns, no session or session was closed
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);
}
}
很可能您在 using (ISession ...
之外访问 DerbySpawns
,而在其上启用了延迟加载。
由于session被using
释放,延迟加载不会发生
您必须确保会话关闭后不会发生延迟加载。
- 在
using (ISession ...
内完成整个工作单元。 - 或在
using (ISession ...
中获取您的依赖项:- 使用预先加载(
.FetchMany
在您的查询中)。当心,结合您的 'random sort',这很可能会导致您 this bug (tagged as EF but I am quite confident NH would have it too), forcing you to use a more complex 'random sort'. - 或者通过访问属性来触发延迟加载。如果这只是一个 'dummy' 访问,那就太脏了...
- 或者在映射中强制获取此集合(影响所有
DerbyArena
加载,也很可能导致前面提到的错误)。
- 使用预先加载(