我需要能够取消长时间运行的只读取数据的NHibernate查询

时间:2012-10-15 16:56:31

标签: c# nhibernate

所以我搜索了互联网和S.O.但我似乎无法找到问题的答案。我看到一些地方人们可以取消东西,因为他们正在使用IQueryable,但在我的情况下,我有一个存储库,我正在返回一个列表,但我希望能够取消对返回数据的查询的调用 - 嗯,我不知道我解释得那么好。希望这段代码片段能够更加清晰。

 public class EdiRepository : GenericRepository<EdiEventLog, Guid>, IEdiRepository
{
    private readonly ISessionStorage _sessionStorage;
    private ISession _session;

    public EdiRepository(ISessionStorage sessionStorage)
        : base(sessionStorage)
    {
        _sessionStorage = sessionStorage;
    }

    public void Cancel()
    {
        //Uhm, this doesn't seem like the right thing to do. 
        _session.Dispose();
    }

    public IList<EdiEventLog> GetAllLogs(List<String> eventTtypes)
    {
        _session = GetSession();

        var query = from q in _session.Query<EdiEventLog>()
                    where eventTtypes.Contains(q.EventType)
                    select q;

        return query.ToList();
    }
}

如果这是多余的而且我错过了它,请指出我正确的方向,但我所看到的一切都假设您正在返回并且IQueryable不是列表。

感谢

2 个答案:

答案 0 :(得分:4)

调用_session.CancelQuery();(当然,来自不同的线程,因为您的查询线程将在查询调用时被阻止)。它会抛出一个特定于数据库的查询取消异常。

请注意,这仅适用于您的查询仍在数据库上运行的情况。如果查询调用已经从返回的数据创建.NET对象,它将不会取消任何内容。

答案 1 :(得分:-1)

我会实施我自己的取消方法,它会更快地返回部分结果

public IEnumerable<IList<EdiEventLog>> GetAllLogs(List<String> eventTtypes)
{
    _session = GetSession();
    const int pagesize = 1000;
    int page = 0;
    var query = from q in _session.Query<EdiEventLog>()
                where eventTtypes.Contains(q.EventType)
                orderby q.Id   // to make sure repeated queries return consistent results
                select q;

    IList<EdiEventLog> results;
    do
    {
        results = query.Skip(page * pagesize).Take(pagesize).ToList();
        page++;
    } while(results.Count > 0);
}

并使用它

foreach(var someLogs in GetAllLogs(eventTypes))
{
    AddToGui(someLogs);
    if (userCanceled)
        break;
}