我必須讀一個大的記錄集,處理它,然後寫出一個平面文件。NHibernate - 流大的結果集?
大的結果集來自於一個存儲過程在SQL 2000
我目前有:
VAR的結果=執行Session.createSQLQuery( 「EXEC usp_SalesExtract」)名單();
我希望能夠按行讀取結果集行,減少內存佔用
感謝
我必須讀一個大的記錄集,處理它,然後寫出一個平面文件。NHibernate - 流大的結果集?
大的結果集來自於一個存儲過程在SQL 2000
我目前有:
VAR的結果=執行Session.createSQLQuery( 「EXEC usp_SalesExtract」)名單();
我希望能夠按行讀取結果集行,減少內存佔用
感謝
NHibernate的不是設計用於使用。另外,你並沒有真正使用它的功能。
因此,在這種情況下,最好使用原始的ADO.NET。
最好只使用SQL Server,它的工作是處理大型結果集。 – 2010-05-25 11:43:01
爲什麼不直接使用SQL Server的BCP實用工具:http://msdn.microsoft.com/en-us/library/aa174646%28SQL.80%29.aspx寫在文件存儲過程。如果您需要對數據進行邏輯處理,請修改該程序以執行您的需要。
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] ...)
}
如果你可以用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()));
}
爲什麼還要使用NHibernate的或ADO.NET,他們只是增加了複雜性和開銷層,當SQL Server可以通過自身與BCP做這一切或SSIS? – 2010-05-25 11:42:04