2010-05-24 67 views
1

我必须读一个大的记录集,处理它,然后写出一个平面文件。NHibernate - 流大的结果集?

大的结果集来自于一个存储过程在SQL 2000

我目前有:
VAR的结果=执行Session.createSQLQuery( “EXEC usp_SalesExtract”)名单();

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

感谢

+0

为什么还要使用NHibernate的或ADO.NET,他们只是增加了复杂性和开销层,当SQL Server可以通过自身与BCP做这一切或SSIS? – 2010-05-25 11:42:04

回答

3

NHibernate的不是设计用于使用。另外,你并没有真正使用它的功能。

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

+0

最好只使用SQL Server,它的工作是处理大型结果集。 – 2010-05-25 11:43:01

1

NHibernate不允许直接执行此操作。

可以使用session.Connection财产与ADO.NET SqlDataReader做到这一点:

SqlCommand MyCommand = new SqlCommand("sp_SalesExtract", session.Connection); 
MyCommand.CommandType = CommandType.StoredProcedure; 
SqlDataReader MyDataReader = MyCommand.ExecuteReader(); 

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

如果你可以用LINQ查询的数据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())); 
}