我正在使用 Fluent NHibernate 和 Microsoft 依赖注入和存储库模式开发一个游戏服务器项目。我有一个包含 OpenSession 函数的数据库管理器类:
ublic class DatabaseManager : IDatabaseManager
{
private readonly ISessionFactory _sessionFactory;
public DatabaseManager(ServerConfig serverConfig)
{
var mcsb = new MySqlConnectionStringBuilder()
{
Server = serverConfig.Database.Hostname,
UserID = serverConfig.Database.Username,
Password = serverConfig.Database.Password,
Database = serverConfig.Database.Name,
Pooling = serverConfig.Database.Pooling,
MinimumPoolSize = serverConfig.Database.MinPool,
MaximumPoolSize = serverConfig.Database.MaxPool
};
_sessionFactory = Fluently.Configure()
.Database(MySqlConfiguration.Standard.ConnectionString(mcsb.ToString()))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Server>())
.BuildSessionFactory();
}
public ISession OpenSession()
{
return _sessionFactory.OpenSession();
}
}
然后,我有一个带有关系的用户模型,例如:
public virtual IEnumerable<Transaction> Transactions { get; } = new List<Transaction>();
我有一个用户登录的事件,这是我将用户对象设置为数据库中的正确对象的地方,如下所示:
public async Task Handle(Session session, GameRequest request)
{
var user = _userRepository.GetUserByToken(request.ReadString());
if (user == null)
{
// TODO: Throw error...
await session.Disconnect();
return;
}
session.User = user;
}
然后我有这个基本的 Repository 类:
public class Repository<T> : IRepository<T>
{
private readonly IDatabaseManager _databaseManager;
protected Repository(IDatabaseManager databaseManager)
{
_databaseManager = databaseManager;
}
public object Add(T entity)
{
using var session = _databaseManager.OpenSession();
var result = session.Save(entity);
session.Flush();
session.Dispose();
return result;
}
public void Delete(T entity)
{
using var session = _databaseManager.OpenSession();
session.Delete(entity);
session.Flush();
session.Dispose();
}
public void Update(T entity)
{
using var session = _databaseManager.OpenSession();
session.Update(entity);
session.Flush();
session.Dispose();
}
public T? Find(object id)
{
using var session = _databaseManager.OpenSession();
return session.Get<T>(id);
}
public IEnumerable<T> FindAll()
{
using var session = _databaseManager.OpenSession();
return session.Query<T>().ToList();
}
public IEnumerable<T> FindAllBy(DetachedCriteria criteria)
{
using var session = _databaseManager.OpenSession();
return criteria.GetExecutableCriteria(session).List<T>();
}
public T? FindOneBy(DetachedCriteria criteria)
{
using var session = _databaseManager.OpenSession();
return criteria.GetExecutableCriteria(session).UniqueResult<T?>();
}
}
还有一个 UserRepository 类:
public class UserRepository : Repository<User>
{
public UserRepository(IDatabaseManager databaseManager) : base(databaseManager)
{
}
public User? GetUserByToken(string token)
{
return FindOneBy(DetachedCriteria.For<User>().Add(Restrictions.Eq("Token", token)));
}
}
登录工作正常,但在另一个事件中我尝试使用
session.User.Transactions
它给出了以下错误:
failed to lazily initialize a collection of role: User.Transactions, no session or session was closed
我读了一些关于它的内容,但我不确定修复它的最佳方法是什么,特别是考虑到它必须与多个连接的客户端一起工作。我只能让它急切地加载,但我认为这不是正确的方法