【问题标题】:Passing objects from stored procedure for serialization with XML从存储过程传递对象以使用 XML 进行序列化
【发布时间】:2014-02-13 21:29:45
【问题描述】:

我有一个定义的对象列表。我想从存储过程中填充它们,然后将它们序列化以传递给 XML 文件。我被困在如何做到这一点上。这是我到目前为止所拥有的。我不想使用 LINQ。

在图书馆类中我有这个:

public class Person
{
    public static string First_Name { get; set; }
    public static string Last_Name { get; set; }    
    public static string Address1 { get; set; }
    public static string Address2 { get; set; }
}

在数据库类中我有这个:

conn = new SqlConnection(ConfigurationManager.AppSettings["DatabaseConnection"]);

            using (var cmd = new SqlCommand())
            {
                conn.Open();
                cmd.Connection = conn;
                cmd.CommandType = System.Data.CommandType.StoredProcedure;
                cmd.CommandText = "sp_GetInfo";

                cmd.Parameters.Add(CreateParameter("@Id", SqlDbType.Int, Id));

                SqlDataReader dr = cmd.ExecuteReader();

                if (dr.Read())
                {
                    string First_Name = dr.GetString(0);
                    string Last_Name = dr.GetString(1);
                    string Address1 = dr.GetString(2);
                    string Address2 = dr.GetString(3);                      

                    dr.Close();
                    dr.Dispose();
                }

为了序列化我打算使用这个:

public static string Serialize(object obj)
    {
        XmlSerializer xs = new XmlSerializer(obj.GetType());
        MemoryStream buffer = new MemoryStream();
        xs.Serialize(buffer, obj);
        return ASCIIEncoding.ASCII.GetString(buffer.ToArray());
    }

我是在正确的道路上还是我需要以不同的方式看待这个问题?

【问题讨论】:

标签: c# sql sql-server xml xml-serialization


【解决方案1】:

您走在正确的道路上。请注意,当您从存储过程中读取数据时(顺便避免“sp_”前缀;这是 MS 存储过程的约定),您需要创建您列出的 Person 对象。

在序列化方面,更简单的版本是使用StringWriter类:

        public static string Serialize(object obj)
        {
            XmlSerializer xs = new XmlSerializer(obj.GetType());
            using (StringWriter textWriter = new StringWriter())
            {
                xs.Serialize(textWriter, obj);
                return textWriter.ToString();
            }
        }

注意using 语句的使用,它强制在IDisposable 对象上调用Dispose()。

【讨论】:

    【解决方案2】:

    这是我用于对对象进行 serzing 的代码片段

        public static string XmlString<X>(X obj, bool omitXmlDeclaration = false, bool omitNameSpace = false)
        {
            var xSer = new XmlSerializer(typeof(X));
    
            var settings = new XmlWriterSettings() { OmitXmlDeclaration = omitXmlDeclaration, Indent = true, Encoding = new UTF8Encoding(false) };
            using (var ms = new MemoryStream())
            using (var writer = XmlWriter.Create(ms, settings))
            {
                if (!omitNameSpace)
                {
                    xSer.Serialize(writer, obj);
                }
                else
                {
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");
                    xSer.Serialize(writer, obj, ns);
                }
                ms.Seek(0, 0);
                return new UTF8Encoding(false).GetString(ms.GetBuffer(), 0, (int)ms.Length);
            }
        }
    

    在大量存储 XML 时,有时您可能希望省略不必要的文本以节省空间,因此这允许您省略 xml 声明和命名空间。

    注意 using 语句堆叠的使用,我想将其用作关于您的连接打开的另一个建议的转义。

    这是我发现在使用直接 ADO.NET 时非常有用的模板

    using(var conn=new SqlConnection(""))
    using(var cmd=new SqlCommand("[sqltext||sproc]",conn)){
    //setup cmd with type of sql to execute
    //establish a data reader
        conn.Open();//at the latest possible moment
        using(var dr=cmd.ExecuteReader()){
            //do assignments
        }
    }
    

    这只是一个脚手架。您必须填写详细信息并根据需要调整阅读器执行。

    最后,如果您计划进行任何二进制序列化或使用 proc 之外的会话(例如使用 SQL Server 支持的 ASP.NET 会话),您应该将您的类标记为 Serializable。

    【讨论】:

      猜你喜欢
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-18
      • 2017-10-22
      相关资源
      最近更新 更多