login  Naam:   Wachtwoord: 
Registreer je!
 Forum

[C#] datatable to class (Opgelost)

Offline jerone - 26/05/2009 16:06 (laatste wijziging 26/05/2009 16:07)
Avatar van jeroneJS gevorderde Ik heb een class gemaakt voor Patient. Elke patient heeft zo zijn eigen gegevens; naam, bsn, leeftijd, etc... Meerdere patienten worden opgeslagen in een class Patienten.
Al deze informatie staat in een database en krijg ik terug in een datatable/dataset.

Nu wil ik dat elke patient in deze database gedefinieerd word als een new Patient().

In XML gaat dit heel makkelijk d.m.v. deze code:
  1. public Patienten LoadXml(string location) {
  2. Patienten patienten = new Patienten();
  3. XmlSerializer xs = new XmlSerializer(typeof(Patienten));
  4. TextReader tr = new StreamReader(location);
  5. patienten = (Patienten)xs.Deserialize(tr);
  6. tr.Close();
  7. return patienten;
  8. }

Nou was mijn vraag of dit ook zo makkelijk kan met een datatable/dataset of moet ik alles manual vullen?!

10 antwoorden

Gesponsorde links
Offline Ontani - 26/05/2009 16:16
Avatar van Ontani Gouden medailleGouden medailleGouden medailleGouden medaille

-1
Je kan doorheen je dataset lopen en bijvoorbeeld

Patienten patient = new Patienten(dataset.tables(0).rows(i));

En in de constructor van je class alle properties invullen met de gegevens uit de datarow.
Offline jerone - 26/05/2009 16:21
Avatar van jerone JS gevorderde jah, je bedoelt de 'manual way'.

foreach(Row row in dt.rows) etc

Ik had gehoopt een meer simpelere manier, zoals de xml manier.
Offline Ontani - 26/05/2009 16:23
Avatar van Ontani Gouden medailleGouden medailleGouden medailleGouden medaille

-1
Bij mijn weten is er geen standaard klasse die dit voor je doet.
Offline Abbas - 26/05/2009 17:10
Avatar van Abbas Gouden medaille

Crew .NET
Inderdaad, er is niet direct een methode om alles uit de DataSet in één keer in een object Patienten te stoppen aangezien een DataSet gegevens bevat en jouw code "weet" niet dat het om een Patient per rij gaat. Achter al dat .NET werk steekt ook een methode die het doet vergelijkbaar met de foreach() voor die DataSet. En ik snap ook al niet waarom je een aparte klasse hebt voor patienten. Waarom maak je niet een List aan binnen de klasse Patient, die List is dan ter vervanging van nog eens een aparte klasse.
Offline jerone - 27/05/2009 00:13
Avatar van jerone JS gevorderde Oké voor de geïnteresseerde; dit artikel bevat bijna de hele oplossing.

Het enige missende gedeelte is dat het alleen maar werkt met strings. Als een property bijvoorbeeld een int is werkt het niet meer.
Ik ben al achter gekomen dat het probleem ligt bij:
oField.SetValue(...);
Maar ik weet niet hoe ik het moet oplossen.

Iemand enig idee.
Offline Ontani - 27/05/2009 08:28
Avatar van Ontani Gouden medailleGouden medailleGouden medailleGouden medaille

-1
Een zelfgemaakte klasse dus. Je kan het met andere woorden beter manueel oplossen.
Offline Ultimatum - 27/05/2009 11:28 (laatste wijziging 27/05/2009 11:29)
Avatar van Ultimatum PHP expert
jerone schreef:
Oké voor de geïnteresseerde; dit artikel bevat bijna de hele oplossing.

Het enige missende gedeelte is dat het alleen maar werkt met strings. Als een property bijvoorbeeld een int is werkt het niet meer.
Ik ben al achter gekomen dat het probleem ligt bij:
oField.SetValue(...);
Maar ik weet niet hoe ik het moet oplossen.

Iemand enig idee.

Nee alle waardes van de velden uit de database worden opgeslagen in de class die staat in het bestand Structures.cs. Daar moet je de velden uit je eigen tabel invullen en daar staat ook overal string voor (op die website) de variable. Heb je daar al gekeken want ik denk dat je het zo wel kan oplossen.
Offline jerone - 27/05/2009 12:52
Avatar van jerone JS gevorderde Het probleem zit in deze regel:
oField.SetValue(this, oRow[oColumnAttributeName.ColumnName]);

Als ik ga debuggen staat in oRow alle juiste waarden, ook alle int en DateTime.
Maar als ik bij de this ga kijken word alleen de string waardes gevult.
Als ik door de oField loop zie ik wel netjes alle datatypes voorbij gaan;
System.String en Int32
Maar het resultaat is dat ik bij geen string elke x de standaard waarde krijg en dat de loop stop, dus alles wat daarna komt wordt negeerd.
Offline Ultimatum - 27/05/2009 13:42
Avatar van Ultimatum PHP expert Kan je eens laten zien wat je al hebt, want misschien heb je met het veranderen een fout gemaakt. Ik zie nu ook dit stukje:
  1. for(i=0;i<Max;i++)
  2. {
  3. foreach(DataRow oRow in oTable.Rows)
  4. {
  5. oEmployee = new Sample.Employee();
  6. oEmployee.EmployeeID = Convert.ToInt32(oRow["EmployeeID"]);
  7. oEmployee.FirstName = oRow["FirstName"].ToString();
  8. oEmployee.LastName = oRow["LastName"].ToString();
  9. oEmployee.BirthDate = (DateTime)oRow["BirthDate"];
  10. oEmployee.Address = oRow["Address"].ToString();
  11. oEmployee.City = oRow["City"].ToString();
  12. oEmployee.PostalCode = oRow["PostalCode"].ToString();
  13. oEmployee.HomePhone = oRow["HomePhone"].ToString();
  14. oEmployee.Country = oRow["Country"].ToString();
  15. }
  16. }


Heb je ook .ToString() er achter gezet? Zoja, haal die eens weg dan. Verder kan ik niets zonder code omdat het nu giswerk word zoals ik hierboven al doe.
Offline jerone - 27/05/2009 14:57 (laatste wijziging 27/05/2009 16:16)
Avatar van jerone JS gevorderde Hey,

Het probleem is dat ik me code niet online mag publiceren (wat trouwens ook teveel is). 

Die code die jij hierboven hebt is dus de 'oude' manier, zoals in da artikel staat aangegeven. Als ik deze manier gebruik werkt het wel.

Maar mijn bedoeling is dus nu de 'nieuwe' manier te gebruiken met dit idee:
  1. oEmployee = new Sample.Employee();
  2. object[,] oFields = oEmployee.GetFields(typeof(Sample.Employee));
  3.  
  4. foreach(DataRow oRow in oTable.Rows)
  5. {
  6. oEmployee = new Sample.Employee();
  7. oEmployee.SetFields(oFields,oRow);
  8. // deze oEmployee ergens opslaan, geen probleem;
  9. }

Het probleem zit hem bij mij nu in wanneer ik een andere datatype moet converteren. In het artikel bedoel ik dan bijv. de code:
  1. [ColumnAttributes("EmployeeID")]
  2. public int EmployeeID;
of
  1. [ColumnAttributes("BirthDate")]
  2. public DateTime BirthDate;


Zodra ik ook bij die SetValue functie kom, geeft hij ook aan:
Citaat:
Een object van type System.String kan niet naar het type System.DateTime worden geconverteerd.


------- EDIT -------
Oke, ik heb het gedeeltelijk opgelost door gebruik te maken van Convert.ChangeType():
  1. oField.SetValue(this, Convert.ChangeType( oRow[oColumnAttributeName.ColumnName],oField.FieldType));

Enige probleem waar ik nu weer tegenaan hik, is als het type een gedefineerde enum is.

Iemand die hiervoor de oplossing heeft?

----------- EDIT 2 --------------
Oke, ik heb het nu zo opgelost:
  1. try {
  2. oField.SetValue(this, Convert.ChangeType(oRow[oColumnAttributeName.ColumnName], oField.FieldType));
  3. }
  4. catch (Exception e) {
  5. try {
  6. int ii = Convert.ToInt32(oRow[oColumnAttributeName.ColumnName]);
  7. object oo = Enum.ToObject(oField.FieldType, ii);
  8. oField.SetValue(this, oo);
  9. }
  10. catch (Exception ee) { }
  11. }

Iemand die een betere oplossing heeft...

i.i.g. bedankt allemaal. gr J
Gesponsorde links
Dit onderwerp is gesloten.
Actieve forumberichten
© 2002-2024 Sitemasters.be - Regels - Laadtijd: 0.243s