Home > other >  Storing serialized data in a SQL Server XML / string column with DataTable and DataAdapter
Storing serialized data in a SQL Server XML / string column with DataTable and DataAdapter

Time:01-24

I wonder if someone can help me thru this scenario:

In SQL Server, I have a column of type XML or string . My application has a serializable data object which I want to store in that column.

The DataColumn in my DataTable has the type of this object. But when I try to update my database I get the exception

No mapping exists from object type […] to a known managed provider native type

This is actually clear, but is there a way to inject a converter / mapper doing this typed serialization and deserialization while Fill and Update using DataAdapter?

[Edit] This shall be the data flow

CodePudding user response:

Yes, I do that. My column definition in the SQL Server table is:

[FileData] [varchar](max) NOT NULL

The Dataset in my app is defined like this, a string:

enter image description here

CodePudding user response:

An Exception

No mapping exists from object type […] to a known managed provider native type

appears when you forget to serialize an object when working with an xml column. Here is an example of the correct approach when working with xml type fields

    using (SqlConnection cnn = new SqlConnection(connectionString))
{
    string sql = "INSERT INTO Sale_T(SaleID, SaleInfo) values(@SaleId, @SaleInfo);";
    cnn.Open();
    using (SqlCommand cmd = new SqlCommand(sql, cnn))
    {
        Sale saleInfo = new Sale
        {
            Client = "Thomas",
            SaleDate = DateTime.Now,
            Items = new List<Product> {
                new Product { ProductName = "Apple", Price = 1.5 },
                new Product { ProductName = "Orange", Price = 0.8 } }
        };
        cmd.Parameters.AddWithValue("@SaleId", 2);
        // An attempt to directly assign an object leads to System.ArgumentException "No mapping exists from object type Sale to a known managed provider native type."
        // cmd.Parameters.AddWithValue("@SaleInfo", saleInfo);
        // you have to pre-serialize

        var Ser2String = (Sale si) =>  { 
            XmlSerializer mySerializer = new XmlSerializer(typeof(Sale));
            using (StringWriter stringWriter = new StringWriter())
            {
                mySerializer.Serialize(stringWriter, si);
                return stringWriter.ToString();
            }
        };

        string serSale = Ser2String(saleInfo);
        cmd.Parameters.AddWithValue("@SaleInfo", serSale);
        cmd.ExecuteNonQuery();
    }
}

OK, here's the continuation of the story, only now using

void DataAdapterFillExample(){
using (SqlConnection con = new SqlConnection(connectionString))
{
    using (SqlCommand cmd = new SqlCommand("SELECT * FROM Sale_T", con))
    {
        cmd.CommandType = CommandType.Text;
        using (SqlDataAdapter dataAdapter = new SqlDataAdapter(cmd))
        {
            using (DataTable dataTable = new DataTable())
            {
                dataAdapter.Fill(dataTable);
                foreach (DataRow row in dataTable.Rows)
                {
                    string saleID = row["SaleID"].ToString();
                    // here you can add desSerialization
                    string saleInfo = row["SaleInfo"].ToString();
                    Console.WriteLine($"{saleID} | {saleInfo}");
                }
            }
        }
    }
}

result:

1 | Peter0001-01-01T00:00:00Apple1.5Orange0.8 2 | Thomas2023-01-23T18:01:50.4545511 03:00Apple1.5Orange0.8

  • Related