将DataTable(数据集)序列化为Object

时间:2013-12-09 07:01:45

标签: c# xml serialization datatable dataset

我从数据库中有一个类和一个查询,在DataSet中填充DataTable。被序列化数据表以填充(对象)标记。

对象:

 public class Marks
    {
        /// <summary>
        /// 
        /// </summary>
        public List<Mark> MarkList { get; set; }

        public Marks()
        {
            MarkList = new List<Mark>();
        }
    }


    public class Mark
    { 
        public String Number { get; set; }

        public String Word { get; set; }

        public DateTime? DateIn { get; set; }

        public DateTime? DateOut { get; set; }
    }

我试图这样做:

private void BindMarksSerialize()
{      
    FillDataTable(dtMarks, MarksCMD);

    MemoryStream stream = new MemoryStream();
    dtMarks.WriteXml(stream);
    XmlSerializer serializer = new XmlSerializer(typeof(Marks), new XmlRootAttribute("Marks")); 
    File.WriteAllBytes("C:\\Out.xml", stream.ToArray());


    StreamReader reader = new StreamReader("C:\\Out.xml");
    var marks = (Marks)serializer.Deserialize(reader);
    reader.Close();
}

private void FillDataTable(DataTable dataTable, Object sqlCommandContainer)
{
    var sqlCommand = sqlCommandContainer as SqlCommand;
    var sqlDataAdapter = sqlCommandContainer as SqlDataAdapter;
    if (sqlDataAdapter == null && sqlCommand == null)
        return;
    try
    {
        dataTable.Clear();
        if (sqlCommand != null)
        {
            sqlCommand.Connection.Open();
            dataTable.Load(sqlCommand.ExecuteReader());
        }
        else
            sqlDataAdapter.Fill(dataTable);
    }
    catch (SqlException ex)
    {
        Logger.Error(new StackTrace(1).GetFrame(0).GetMethod().Name + @": " + Environment.NewLine + ex.Message);
    }
    finally
    {
        if (sqlCommand != null)
            sqlCommand.Connection.Close();
    }
}

填充XML需要结果:

<Marks xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <MarkList>
    <Mark>
      <Number>1</Number>
      <Word>123123123</Word>
      <DateIn xsi:nil="true" />
      <DateOut xsi:nil="true" />      
    </Mark>
  </MarkList>
</Marks>

我得到了:

<NewDataSet>
  <Mark>
    <Number>110938</Number>
    <Word>110938</Word>
    <DateIn>1993-04-08T00:00:00+05:00</DateIn>
    <DateOut>2002-02-04T00:00:00+04:00</DateOut>    
  </Mark>
</NewDataSet>

提示可以有人知道怎么做吗?

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您在将DataSet写入XML文件时遇到问题,但在将标记类类型对象列表写入XML时没有问题。

您可以使用反射来创建可重用的函数,该函数将从任何Datatable读取Datarow并将其分配给您作为参数传递的任何对象。如果您想要该对象的List,那么您可以遍历DataTable的DataRows。在下面的示例中,我将从单行生成一个对象。 (这是一种可重用的映射。)

public static object ConvertDataRowToObject(object Object, DataTable DataTable)
{
    try
    {
        if (DataTable.Rows.Count > 0)
        {
            DataRow DataRow = DataTable.AsEnumerable().FirstOrDefault();
            if (DataRow != null)
            {
                Type ObjectType = Object.GetType();
                //Get public properties
                System.Reflection.PropertyInfo[] _propertyInfo =
                     ObjectType.GetProperties();
                foreach (System.Reflection.PropertyInfo _property in _propertyInfo)
                {
                    _property.SetValue(Object, (DataRow[_property.Name.ToString()] is System.DBNull ? null : DataRow[_property.Name.ToString()]), null);
                }
                return Object;
            }
            else return null;
        }
        else
            return null;
    }
    catch (Exception excp)
    {
        Common.WriteErrorLog(excp.Message);
        return null;
    }
}

现在当我需要调用这个静态可重用函数时,我可以像这个样本一样。

Database _dbFactory = Common.Database;
                DataSet dset = new DataSet();
                Object[] _dbObject = DataBaseHelper.CreateConnection();
                dset = _dbFactory.ExecuteDataSet("Jwl_sp_SearchByProductCategoryById", new object[] { _Id });
                DataBaseHelper.CloseConnection((SqlConnection)_dbObject[0]);
                DataTable dt = new DataTable();
                dt = dset.Tables[0];
                var objectTobeConverted = new DataLogic.Database.Jwl_ByProductCategory();
                ConvertDataRowToObject(objectTobeConverted, dt);

我使用Javascript序列化程序序列化了这个对象。在您的情况下,下一步是写入您可以使用xmlSerialization的xml文档,或者我建议使用XMLWriter。

public static string GetJSONSerializedObject(object myItem)
{
    try
    {
        if (myItem != null)
        {
            List<KeyValuePair<string, string>> _propList = new List<KeyValuePair<string, string>>();

            Type myObjectType = myItem.GetType();
            //Get public properties
            System.Reflection.PropertyInfo[] _propertyInfo =
                 myObjectType.GetProperties();
            foreach (System.Reflection.PropertyInfo _property in _propertyInfo)
            {
                string _key = String.Empty;
                string _value = String.Empty;
                _key = _property.Name.ToString();
                _value = (_property.GetValue(myItem, null) != null) ? Convert.ToString(_property.GetValue(myItem, null)) : "";
                _propList.Add(new KeyValuePair<string, string>(_key, _value));
            }
            if (_propList.Count > 0)
            {// Serializing an object's properties
               System.Web.Script.Serialization.JavaScriptSerializer jsSerializer;
                jsSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
                System.Text.StringBuilder _strBuild = new System.Text.StringBuilder();
                jsSerializer.Serialize(_propList, _strBuild);
                return _strBuild.ToString();


            }
            else { return null; }
        }
        else { return null; }
    }
    catch (Exception excp)
    {
        Common.WriteErrorLog(excp.Message);
        return null;
    }
}