NHibernate - 流大型结果集?

时间:2010-05-24 13:43:44

标签: c# database nhibernate stream resultset

我必须在大型记录集中读取,处理它,然后将其写入平面文件。

大型结果集来自SQL 2000中的Stored Proc。

我目前有:
var results = session.CreateSQLQuery(“exec usp_SalesExtract”)。List();

我希望能够逐行读取结果集,以减少内存占用

由于

4 个答案:

答案 0 :(得分:3)

为什么不使用SQL Server bcp Utility:http://msdn.microsoft.com/en-us/library/aa174646%28SQL.80%29.aspx从存储过程中写入文件。如果您需要对数据执行逻辑操作,请修改该过程以满足您的需要。

答案 1 :(得分:3)

NHibernate并非专为此用途而设计。另外,你并没有真正使用它的功能。

因此,在这种情况下,最好使用原始ADO.NET。

答案 2 :(得分:1)

NHibernate不允许直接这样做。

您可以使用SqlDataReader属性

在ADO.NET session.Connection中执行此操作
SqlCommand MyCommand = new SqlCommand("sp_SalesExtract", session.Connection);
MyCommand.CommandType = CommandType.StoredProcedure;
SqlDataReader MyDataReader = MyCommand.ExecuteReader();

while (MyDataReader.Read())
{
    // handle row data (MyDataReader[0] ...)
}

答案 3 :(得分:0)

如果您可以使用Linq to NH查询数据,您可以使用以下扩展方法流式传输结果(如果您不喜欢反射黑客,请传递ISessionImplementor):

public static EnumerableImpl Stream<T>(this IQueryable<T> source)
{
    var provider = ((NhQueryable<T>) source).Provider as DefaultQueryProvider;
    var sessionImpl = (ISessionImplementor)provider.GetType()
        .GetProperty("Session", BindingFlags.NonPublic | 
            BindingFlags.Instance).GetValue(provider);
    var expression = new NhLinqExpression(source.Expression, sessionImpl.Factory);
    var query = sessionImpl.CreateQuery(expression);
    query.SetParameters(expression.ParameterValuesByName);
    provider.SetResultTransformerAndAdditionalCriteria(
        query, expression, expression.ParameterValuesByName);
    return (EnumerableImpl)((AbstractQueryImpl2)query).Enumerable();
}

private static void SetParameters(this IQuery query, 
    IDictionary<string, Tuple<object, IType>> parameters)
{
    foreach (var parameterName in query.NamedParameters)
    {
        var param = parameters[parameterName];
        if (param.Item1 == null)
        {
            if (typeof(IEnumerable).IsAssignableFrom(param.Item2.ReturnedClass) &&
                param.Item2.ReturnedClass != typeof(string))
                query.SetParameterList(parameterName, null, param.Item2);
            else query.SetParameter(parameterName, null, param.Item2);
        }
        else
        {
            if (param.Item1 is IEnumerable && !(param.Item1 is string))
                query.SetParameterList(parameterName, (IEnumerable)param.Item1);
            else if (param.Item2 != null)
                query.SetParameter(parameterName, param.Item1, param.Item2);
            else query.SetParameter(parameterName, param.Item1);
        }
    }
}

您需要将其包装在using语句中以确保阅读器已关闭:

using (var results = session.Query<Fark>().Take(50).Where(x => x.Enabled).Stream())
{
    results.ForEach(x => writer.WriteLine(x.ToCsv()));
}