简体   繁体   English

C#(将数据集转换为多个CSV字符串,保留类型并转换回)

[英]C# (Convert DataSet to multiple CSV strings, preserving types, and convert back)

I just ran into a problem. 我遇到了一个问题。 I was trying to serialize a DataSet into json and encrypt it using jose-jwt . 我试图将DataSet 序列化为json并使用jose-jwt对其进行加密。 But it didn't work, I don't know the reason, but when trying to retrieve, the data was blank. 但这不起作用,我不知道原因,但是在尝试检索时,数据为空白。

What I need is a way to convert the DataSet to List of CSVs and get it back, but preserving the Column Types. 我需要的是一种将DataSet转换为CSV列表并取回的方法,但保留了列类型。

Then I come with this Code that I want to share, and ask if someone have an easier way to do it. 然后,我提供了此代码,我想与他人分享,并询问是否有人有更简单的方法来实现它。 (I'm here to learn after all) (毕竟我是来这里学习的)

It has an option that add an extra column for each column and only in header it writes the DataColumn.DataType. 它具有为每个列添加一个额外列的选项,并且仅在标头中写入DataColumn.DataType。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading;

namespace Demo
{
    public static class Utilities
    {
        private static char separator = '|';

        public static List<string> ToCSV(this DataSet ds, bool withTypes = false)
        {    
            List<string> lResult = new List<string>();

            foreach (DataTable dt in ds.Tables)
            {
                StringBuilder sb = new StringBuilder();
                IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().
                                                  Select(column => (column.ColumnName + (withTypes ? separator + column.DataType.ToString() : "")));
                sb.AppendLine(string.Join(separator.ToString(), columnNames));

                foreach (DataRow row in dt.Rows)
                {
                    IEnumerable<string> fields = row.ItemArray.Select(field => $"{field.ToString().Replace("\"", "\"\"").Replace(Environment.NewLine, " ")}{(withTypes ? separator + "" : "") }");
                    sb.AppendLine(string.Join(separator.ToString(), fields));
                }

                lResult.Add(sb.ToString());
            }

            return lResult;
        }

        public static DataSet CSVtoDataSet(this List<string> collectionCSV, bool withTypes = false) //, char separator = '|')
        {    
            var ds = new DataSet();

            foreach (var csv in collectionCSV)
            {
                var dt = new DataTable();

                var readHeader = false;
                var lines = csv.Split(new[] { Environment.NewLine }, StringSplitOptions.None);

                foreach (var line in lines)
                {
                    if (!readHeader)
                    {
                        readHeader = true;
                        List<string> splited = line.Split(separator).ToList();

                        for (int i = 0; i < splited.Count; i++)
                        {
                            var columnName = splited[i];
                            var columnType = typeof(string);

                            if (withTypes && splited.Count > 1)
                            {
                                i++;
                                if (lines.Count() > 1)
                                {
                                    columnType = Type.GetType(splited[i]);
                                }
                            }

                            dt.Columns.Add(new DataColumn { ColumnName = columnName, DataType = columnType, AllowDBNull = true });
                        }
                    }
                    else
                    {
                        var splitedRow = line.Split(separator).ToList();

                        List<object> currentRow = new List<object>();

                        for (int i = 0; i < splitedRow.Count; i++)
                        {
                            if (withTypes && splitedRow.Count > 1)
                            {
                                var inputValue = splitedRow[i];
                                var t = dt.Columns[i / 2].DataType;

                                TypeConverter typeConverter = TypeDescriptor.GetConverter(t);
                                object propValue = string.IsNullOrEmpty(inputValue) ? null : typeConverter.ConvertFromString(inputValue);

                                currentRow.Add(propValue);
                                i++;//Next (0/2)
                            }
                            else
                            {
                                currentRow.Add(splitedRow[i]);
                            }
                        }

                        if (!currentRow.All(x => string.IsNullOrEmpty(x.ToString())))
                            dt.Rows.Add(currentRow.ToArray());
                    }
                }

                ds.Tables.Add(dt);
            }

            return ds;
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM