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
?
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:
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