C# 将延迟加载的Fluent Nhibernate POCO传递给多个工作线程

C# 将延迟加载的Fluent Nhibernate POCO传递给多个工作线程,c#,multithreading,nhibernate,fluent-nhibernate,poco,C#,Multithreading,Nhibernate,Fluent Nhibernate,Poco,我正在寻找一些关于如何处理POCO实例的建议,这些实例由Nhibernate(如果有什么不同的话,请使用流利的Nhibernate)惰性加载 我正在开发一个通用的变更日志实现。进行完全定制实现的原因是,更改数据必须以非常特定的格式写入,以用于不同的目的。并非所有需要的信息都可以直接从POCO实例中访问,而是必须进行计算。最终结果是,更改数据将被写入一个独立于操作数据库的数据库。写入数据的操作将使用SqlCommand完成 因为实现必须是泛型的,以支持当前的POCO类以及将来的任何添加,所以它将使

我正在寻找一些关于如何处理POCO实例的建议,这些实例由Nhibernate(如果有什么不同的话,请使用流利的Nhibernate)惰性加载

我正在开发一个通用的变更日志实现。进行完全定制实现的原因是,更改数据必须以非常特定的格式写入,以用于不同的目的。并非所有需要的信息都可以直接从POCO实例中访问,而是必须进行计算。最终结果是,更改数据将被写入一个独立于操作数据库的数据库。写入数据的操作将使用SqlCommand完成

因为实现必须是泛型的,以支持当前的POCO类以及将来的任何添加,所以它将使用反射来提取传递给更改日志记录实现的POCO的属性

我得到的是:

public interface IChangeLogger
{
    void Log(BaseEntity entity);
}
其中BaseEntity是每个POCO继承的类

实施过程非常简单

public class DefaultChangeLogger : IChangeLogger
{
    private readonly string _connectionString;

    public DefaultChangeLogger()
    { 
        var connectionString = ConfigurationManager.ConnectionStrings["ChangeLogger"];
        Guard.Against<ConfigurationErrorsException>(connectionString == null || string.IsNullOrEmpty(connectionString.ConnectionString));
        _connectionString = connectionString.ConnectionString;
    }

    public void LogChange(BaseEntity entity)
    {
        var logger = new SqlServerDirectChangeLogger(_connectionString, entity);
        var starter = new ThreadStart(logger.Log);
        var workerThread = new Thread(starter) { IsBackground = true };
        workerThread.Start();
    }
}
使用单独线程的原因不是为了让应用程序(MVC3、IIS7.5)陷入困境,而是在低优先级的后台线程中进行格式化和日志记录。当前端用户更新一条记录时,我不想延迟响应,因为记录器需要同步进行

因此,SqlServerDirectChangeLogger.Log()将要做的是使用反射来提取属性值,并加载一些额外的元数据,然后将这些元数据写入单独的数据库中,以类似键值的格式更改日志表

问题如下:

  • Web应用程序使用范围为PerWebRequest的ISession。DefaultChangeLogger将具有Singleton的生命周期。如果我传入一个延迟加载的POCO并计算可能触发延迟加载的属性,则需要一个开放的ISession。ISession可能会在需要时关闭
  • 可以让NHibernate“完成”POCO实例吗?通过finalize,我的意思是强制延迟加载到某个级别,并可能断开ISession

    通过在IIS工作线程和派生的工作线程之间传递上述实例,我是否可以预测任何其他问题

    关于如何实现更改日志记录有更好的想法吗?:)


    感谢您的帮助。

    您应该将对象的id传递给工作线程,然后在该线程中重新查询它。

    谢谢您的建议。我确实想到了这种方法,这可能是我不得不求助的方法。
    public class SqlServerDirectChangeLogger
    {
        private readonly string _connectionString;
        private readonly BaseEntity _entity;
    
        public SqlServerDirectChangeLogger(string connectionString, BaseEntity entity)
        {
            _connectionString = connectionString;
            _entity = entity;
        }
    
        public void Log()
        { 
    
        }
    }