[ Mikelly @ 10.08.2009. 17:48 ] @
Ovako,

imam datatable koji je sacinjen u potpunosti od izracunatih podataka, i ne bih htio da cuvam te podatke u bazi. Medjutim, moze se desiti da se nacin racunanja promijeni, pa ce mi ti izracunati podaci ipak trebati.

Onda mi je palo na pamet da xml tog datatable objekta smjestim u xml polje u bazi (neke tamo backup tabele). I krenuh polako... Evo do cega sam dosao:

Code:

System.IO.StringWriter sw = new System.IO.StringWriter();
System.Xml.XmlTextWriter xmltw = new System.Xml.XmlTextWriter(sw);
abakusDataSet.z_Radnici.WriteXml(xmltw, XmlWriteMode.IgnoreSchema);

System.IO.MemoryStream memStream = new System.IO.MemoryStream();
byte [] data = Encoding.Default.GetBytes(sw.ToString());
data = Encoding.GetEncoding("windows-1250").GetBytes(sw.ToString());
data = Encoding.ASCII.GetBytes(sw.ToString());
data = Encoding.Unicode.GetBytes(sw.ToString());
memStream.Write(data, 0, data.Length);
System.Xml.XmlTextReader xmltr = new System.Xml.XmlTextReader(memStream); 

//...connection i command...
cmd.CommandText = "UPDATE z_Obracuni SET Backup_porezi = @XML WHERE ID_Obracun = 1";
cmd.Parameters.Add(new System.Data.SqlClient.SqlParameter("@XML", SqlDbType.Xml));
cmd.Parameters["@XML"].Value = new System.Data.SqlTypes.SqlXml(xmltr);
cmd.Parameters["@XML"].Value = new System.Data.SqlTypes.SqlXml(memstream);
cmd.ExecuteNonQuery();


Mislim da imam dva problema, u kodiranju i nesto sa kreiranjem xml fajla.

Limitiran sam sa konstruktorom SqlXml tipa koji prihvata ili stream ili xmltextreader, pa krecem odatle.

U zavisnosti koje od kodiranja izaberem, dobijam razlicite greske. Sve ovo kada SqlXml konstruktoru proslijedim stream podataka:

Ako izaberem Unicode dobijam gresku: Name cannot begin with the '.' character, hexadecimal value 0x00. Line 1, position 2.
Ako izaberem Default (utf-8 ja mislim) ili windows-1250 dobijam gresku: Invalid character in the given encoding. Line 2, position 316.
Ako izaberem ASCII: prolazi, ali u bazu umjesto š, č, đ, itd dobijam kuke i kvake.
XML visualizer u svakom slucaju ispravno prikaze generisani XML string.

Ako prosalijedim xmltextreader kao argument konstruktoru uvijek dobijem gresku: Root element is missing. Evo kako izgleda pocetak generisanog XML-a:
Code:

- <AbakusDataSet xmlns="http://tempuri.org/AbakusDataSet.xsd">
- <z_Radnici>
  <ID_Radnik>1</ID_Radnik> 
  <Ime>Milos</Ime> 
  <Prezime>Mijatovic</Prezime> 
  <Maticni_broj>0412981210022</Maticni_broj> 


E sad, ja znam (bar mislim) da bi XML trebao pocinjati sa <?xml version....>. Zasto ga onda ovako generise WriteXML metod datatable-a. Plus, taj metod nema verziju koja prihvata Encoding kao parametar...

Ako neko ima iskustva sa ovim, cijenio bih pomoc. A mislio sam, bice kao 'walk in the park'.

Pozdrav.
[ mmix @ 11.08.2009. 09:48 ] @
xml field moze da sadrzi i fragmente xml-a ne samo kompletne xml fajlove i <xml> header nije neophodan kad baratas sa xml stringovima (to je potrebno u fajlovima da bi se znalo da je fajl xml fajl)

Za pocetak, ako ne koristis niti ces koristiti SQL-ve xml fazone kao sto je xquery vec ti samo treba da imas backup XML fajla onda nemoj uopste koristiti xml polje vec serijalizovani XML fajl strpaj kao string u varchar ili text polje.

Ako bas hoces u xml polje onda pusti sqlclientu da ti odradi posao pretabavanja iz stringa u xml:

Code:
StringWriter sw = new StringWriter();
abakusDataSet.z_Radnici.WriteXml(sw, XmlWriteMode.IgnoreSchema);

//...connection i command...
cmd.CommandText = "UPDATE z_Obracuni SET Backup_porezi = @XML WHERE ID_Obracun = 1";
SqlParameter param = new SqlParameter("@XML", SqlDbType.Xml);
cmd.Parameters.Add(param);
param.Value = sw.ToString();
cmd.ExecuteNonQuery();



A ako bas hoces da koristis SqlXml tip, onda ga generisi direktno preko xmltextreader-a iz string-a

Code:
StringWriter sw = new StringWriter();
abakusDataSet.z_Radnici.WriteXml(sw, XmlWriteMode.IgnoreSchema);

//...connection i command...
cmd.CommandText = "UPDATE z_Obracuni SET Backup_porezi = @XML WHERE ID_Obracun = 1";
SqlParameter param = new SqlParameter("@XML", SqlDbType.Xml);
cmd.Parameters.Add(param);
param.Value = new SqlXml(new XmlTextReader(new StringReader(sw.ToString())));
cmd.ExecuteNonQuery();


u svakom slucaju ti ne treba prebacivanje u binarni stream.
[ Mikelly @ 11.08.2009. 13:36 ] @
Hvala, radi sve ovo super :)

Problem je citavo vrijeme bio u kodnim stranama. Evo kako sam ja to rijesio u medjuvremenu, doduse sa binarnim stream-om.

Code:

System.IO.MemoryStream mem = new System.IO.MemoryStream();
System.Xml.XmlTextWriter xmltw2 = new System.Xml.XmlTextWriter(mem, Encoding.UTF8);
abakusDataSet.z_Radnici.WriteXml(xmltw2, XmlWriteMode.IgnoreSchema);
...
cmd.Parameters["@XML"].Value = new System.Data.SqlTypes.SqlXml(mem);


A probao sam na pocetku i sa varchar(max), isalo je dobro do baze, ali mi se posle bunio kod ReadXML metode. Bice da je i tad bio problem kod kodnih strana. U pravu si ti, treba izbjeci memory stream.

Pozdrav.

PS.

Vidio sam da kada upisem XML u fajl, dobijem header, pa me to malo zbunjivalo. Sad znam zasto :)