SerializationFormat

發布 企業信息化 3


麻煩各位了,看有沒有碰到過這個的,DataSet序列化報錯,錯誤信息為:System.Runtime.Serialization.SerializationException:“內部數組不能擴展到大于 Int32.MaxValue 個元素。”
DataSet為包含30萬條數據且列為180列的一張表,在進行序列化時報錯,求解決方案,google,百度好久好像都說是C#的序列化BUG,麻爪中......,DataSet數據減少就算了,這是客戶進行數據統計分析的一個操作,需要把大批量的數據全部加載并顯示由客戶進行處理,實際數據量可能比這個還要大,至于序列化是因為需要通過Remoting進行數據傳輸,將數據傳到客戶端減少流量消耗,以下代碼是一簡單Demo代碼,同樣會觸發該BUG!
 
    
SerializationFormat
    

1 static void Main(string[] args)
    
2 {
    
3 DataSet ds = new DataSet();
    
4 DataTable dt = new DataTable();
    
5 for (int i = 0; i < 180; i++)
    
6 {
    
7 DataColumn dc = new DataColumn();
    
8 dc.ColumnName = "Column_" + i.ToString();
    
9 dc.DefaultValue = "Test_" + i.ToString();
    
10 dt.Columns.Add(dc);
    
11 }
    
12 DateTime bft = DateTime.Now;
    
13 for (int i = 0; i < 300000; i++)
    
14 {
    
15 DataRow dr = dt.NewRow();
    
16 for (int j = 0; j < 180; j++)
    
17 {
    
18 dr[j] = "Row_" + i.ToString() + "_Column_" + j.ToString();
    
19 }
    
20 dt.Rows.Add(dr);
    
21 }
    
22 DateTime aft = DateTime.Now;
    
23 TimeSpan nspan = aft.Subtract(bft);
    
24 Console.WriteLine("添加300000條數據總共花費{0}ms.,{1}s,{2}m", nspan.TotalMilliseconds,nspan.TotalSeconds,nspan.TotalMinutes);
    
25 ds.Tables.Add(dt);
    
26 byte[] bArrayResult = null;
    
27 try
    28 {
    
29 ds.RemotingFormat = SerializationFormat.Binary;
    
30 MemoryStream ms = new MemoryStream();
    
31 IFormatter bf = new BinaryFormatter();
    
32 bf.Serialize(ms, ds);
    
33 bArrayResult = ms.ToArray();
    
34 ms.Close();
    
35 Console.WriteLine("DataSet文件大小:"+GetFileSize(bArrayResult.LongLength));
    
36 }
    
37 catch (Exception ex)
    
38 {
    
39 throw ex;
    
40 }
    
41 }
    
42
    43 /// <summary>
    44 /// 計算文件大小函數(保留兩位小數),Size為字節大小
    
45 /// </summary>
    46 /// <param name="size">初始文件大小</param>
    47 /// <returns></returns>
    48 public static string GetFileSize(long size)
    
49 {
    
50 var num = 1024.00; //byte
    51 if (size < num)
    
52 return size + "B";
    
53 if (size < Math.Pow(num, 2))
    
54 return (size / num).ToString("f2") + "K"; //kb
    55 if (size < Math.Pow(num, 3))
    
56 return (size / Math.Pow(num, 2)).ToString("f2") + "M"; //M
    57 if (size < Math.Pow(num, 4))
    
58 return (size / Math.Pow(num, 3)).ToString("f2") + "G"; //G
    59 return (size / Math.Pow(num, 4)).ToString("f2") + "T"; //T
    60 }
    

    Sample Demo

/// <summary>
    /// Table2Model
    /// </summary>
    public static class Table2Model {
    #region 公共方法(擴展DataTable)
/// <summary>
     /// DataTable轉換成T
     /// </summary>
     /// <typeparam name="T">實體類型</typeparam>
     /// <param name="table">需轉換的數據table</param>
     /// <returns></returns>
     public static T ToModel<T>(this DataTable table) where T : new() {
     T entity = new T();
     foreach (DataRow row in table.Rows) {
     foreach (var item in entity.GetType().GetProperties()) {
     if (row.Table.Columns.Contains(item.Name)) {
     if (DBNull.Value != row[item.Name]) {
     item.SetValue(entity, ChangeType(row[item.Name], item.PropertyType), null);
     }
     }
     }
     }
     return entity;
     }
     /// <summary>
     /// DataTable轉換成T
     /// </summary>
     /// <typeparam name="T">實體類型</typeparam>
     /// <param name="table">需轉換的數據table</param>
     /// <param name="ext">外延表重名需加的前綴</param>
     /// <returns></returns>
     public static T ToModel<T>(this DataTable table, string ext) where T : new() {
     T entity = new T();
     foreach (DataRow row in table.Rows) {
     foreach (var item in entity.GetType().GetProperties()) {
     if (row.Table.Columns.Contains(ext + item.Name)) {
     if (DBNull.Value != row[ext + item.Name]) {
     item.SetValue(entity, ChangeType(row[ext + item.Name], item.PropertyType), null);
     }
     }
     }
     }
     return entity;
     }
     /// <summary>
     /// DataTable轉換成List<T>
     /// </summary>
     /// <typeparam name="T">實體類型</typeparam>
     /// <param name="table">需轉換的數據table</param>
     /// <returns></returns>
     public static List<T> ToModelList<T>(this DataTable table) where T : new() {
     List<T> entities = new List<T>();
     foreach (DataRow row in table.Rows) {
     T entity = new T();
     foreach (var item in entity.GetType().GetProperties()) {
     if (row.Table.Columns.Contains(item.Name)) {
     if (DBNull.Value != row[item.Name]) {
     item.SetValue(entity, ChangeType(row[item.Name], item.PropertyType), null);
     }
     }
     }
     entities.Add(entity);
     }
     return entities;
     }
     #endregion 公共方法(擴展DataTable)
     #region 私有方法(Convert.ChangeType處理Nullable<>和非Nullable<>)
     /// <summary>
     /// 類型轉換(包含Nullable<>和非Nullable<>轉換)
     /// </summary>
     /// <param name="value"></param>
     /// <param name="conversionType"></param>
     /// <returns></returns>
     private static object ChangeType(object value, Type conversionType) {
     // Note: This if block was taken from Convert.ChangeType as is, and is needed here since we're
     // checking properties on conversionType below.
     if (conversionType == null) {
     throw new ArgumentNullException("conversionType");
     } // end if
     // If it's not a nullable type, just pass through the parameters to Convert.ChangeType
     if (conversionType.IsGenericType &&
     conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) {
     if (value == null) {
     return null;
     } // end if
     // It's a nullable type, and not null, so that means it can be converted to its underlying type,
     // so overwrite the passed-in conversion type with this underlying type
     System.ComponentModel.NullableConverter nullableConverter = new System.ComponentModel.NullableConverter(conversionType);
     conversionType = nullableConverter.UnderlyingType;
     } // end if
     // Now that we've guaranteed conversionType is something Convert.ChangeType can handle (i.e. not a
     // nullable type), pass the call on to Convert.ChangeType
     return Convert.ChangeType(value, conversionType);
     }
     #endregion 私有方法(Convert.ChangeType處理Nullable<>和非Nullable<>)
    }

看看能夠滿足你要不

你不是開玩笑吧,序列化 DataSet ?

不能直接序列化 DataSet,要先保存成為文件:
/// <summary>
    /// 序列和反序列 DataSet
    /// </summary>
    public static void SerializeDataSet()
    {
     //測試數據
     DataSet ds = new DataSet();
     DataTable dt = GetTestData();
     ds.Tables.Add(dt);
     //序列化
     FileStream fs = new FileStream("ds.data", FileMode.Create);
     BinaryFormatter bf = new BinaryFormatter();
     ds.RemotingFormat = SerializationFormat.Binary;
     bf.Serialize(fs, ds);
     fs.Close();
     //清空 DataSet
     ds.Clear();
     fs = new FileStream("ds.data", FileMode.Open);
     //反序列化
     DataSet newDs = (DataSet)bf.Deserialize(fs);
    }
    /// <summary>
    /// 獲取測試數據
    /// </summary>
    /// <returns></returns>
    private static DataTable GetTestData()
    {
     DataTable dtTable = new DataTable();
     //建立字段
     dtTable.Columns.Add("filed1", typeof(int));
     dtTable.Columns.Add("filed2", typeof(string));
     dtTable.Columns.Add("filed3", typeof(bool));
     dtTable.Columns.Add("filed4", typeof(DateTime));
     DataRow row;
     for (int i = 1; i < 10; i++)//新增測試數據
     {
     row = dtTable.NewRow();
     row["filed1"] = i;
     row["filed2"] = "字符串" + i.ToString();
     row["filed3"] = i % 2 == 0;
     row["filed4"] = DateTime.Now;
     dtTable.Rows.Add(row);
     }
     return dtTable;
    }

開個線程分頁傳輸就好了,界面搞個提示框等待中,后臺等全部傳輸完成一起展示,這樣不管你有多少數據都沒事
 
黑龙江36选7结果查询