2010-05-24 64 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())); 
}