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

时间:2013-09-18 11:33:02

标签: c# multithreading nhibernate fluent-nhibernate poco

我正在寻找关于POCO实例可以做什么的一些建议,由Nhibernate延迟加载(如果它有任何区别的话,流畅的NHibernate)。

我正在研究更改日志记录的通用实现。执行完全自定义实现的原因是更改数据必须以非常特定的格式编写以用于不同目的。并非所有需要的信息都可以直接从POCO实例访问,但必须进行计算。最终结果是,更改数据将被写入与操作数据库分开的数据库中。编写数据的行为将使用SqlCommand完成。

因为实现必须是通用的,以支持当前的POCO类以及任何未来的添加,所以它将使用Reflection来提取传递给更改日志记录实现的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();
    }
}

最后是最后的工人实施:

public class SqlServerDirectChangeLogger
{
    private readonly string _connectionString;
    private readonly BaseEntity _entity;

    public SqlServerDirectChangeLogger(string connectionString, BaseEntity entity)
    {
        _connectionString = connectionString;
        _entity = entity;
    }

    public void Log()
    { 

    }
}

拥有一个单独的线程背后的原因不是让应用程序陷入困境(MVC3,IIS7.5),而是在低优先级后台线程中进行格式化和登录。当前端用户更新记录时,我不想延迟响应,因为记录器需要同步执行此操作。

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

问题如下:

  1. Web应用程序使用作用于PerWebRequest的ISession。 DefaultChangeLogger的生命周期为Singleton。如果我传入一个懒惰的Loaded POCO并评估可能触发延迟加载的属性,则需要一个开放的ISession。 ISession可能会在需要时关闭。
  2. 是否有可能让NHibernate“敲定”POCO实例?通过finalize我的意思是强制延迟加载到某个级别并可能断开ISession?

    我可以通过在IIS工作线程和生成的工作线程之间传递上述实例来预测任何其他问题吗?

    如何更好地了解如何实施更改日志记录? :)

    感谢您的任何见解。

1 个答案:

答案 0 :(得分:1)

您可能只需将对象的id传递给工作线程并在该线程中重新查询它。