How to implement IDataReader?

My XML looks like this:

<resultset> <datarow> <datacol>Row 1 - Col 1</datacol> <datacol>Row 1 - Col 2</datacol> <datacol>Row 1 - Col 3</datacol> ... </datarow> ... </resultset> ... 

My question is: how can I implement the IDataReader interface with this XML? I am lost...

I designed this:

 public sealed class SybaseDataReader : IDataReader { private DataSet _dataSet = new DataSet(); #region IDataReader methods implementation // ... } 

Am I on a good way?

Thanks for the constructive and well-explained posts.

+1
c # implementation
source share
3 answers

It is not logical to have a DataSet as a member of System.Data.IDataReader.

Think better in terms of XmlDocumnet, XDocument, or XmlReader.

+2
source share

I wrote a simple implementation of reading files. You can easily adapt this to read an XML file:

 public class MyFileDataReader : IDataReader { protected StreamReader Stream { get; set; } protected object[] Values; protected bool Eof { get; set; } protected string CurrentRecord { get; set; } protected int CurrentIndex { get; set; } public MyFileDataReader(string fileName) { Stream = new StreamReader(fileName); Values = new object[this.FieldCount]; } 

Remember that IDataReader has several methods that you do not need to perform depending on your scenario. But there are probably some implementation methods that you cannot avoid:

  public void Close() { Array.Clear(Values, 0, Values.Length); Stream.Close(); Stream.Dispose(); } public int Depth { get { return 0; } } public DataTable GetSchemaTable() { // avoid to implement several methods if your scenario do not demand it throw new NotImplementedException(); } public bool IsClosed { get { return Eof; } } public bool NextResult() { return false; } public bool Read() { CurrentRecord = Stream.ReadLine(); Eof = CurrentRecord == null; if (!Eof) { Fill(Values); CurrentIndex++; } return !Eof; } private void Fill(object[] values) { //To simplify the implementation, lets assume here that the table have just 3 //columns: the primary key, and 2 string columns. And the file is fixed column formatted //and have 2 columns: the first with width 12 and the second with width 40. Said that, we can do as follows values[0] = null; values[1] = CurrentRecord.Substring(0, 12).Trim(); values[2] = CurrentRecord.Substring(12, 40).Trim(); // by default, the first position of the array hold the value that will be // inserted at the first column of the table, and so on // lets assume here that the primary key is auto-generated // if the file is xml we could parse the nodes instead of Substring operations } public int RecordsAffected { get { return -1; } } 

To implement IDataReader, you must also implement the IDisposable and IDataRecord interfaces.

IDisposable is simple, but IDataRecord can be painful. Again, in this scenario there are some implementation methods that we cannot avoid:

  public int FieldCount { get { return 3;//assuming the table has 3 columns } } public IDataReader GetData(int i) { if (i == 0) return this; return null; } public string GetDataTypeName(int i) { return "String"; } public string GetName(int i) { return Values[i].ToString(); } public string GetString(int i) { return Values[i].ToString(); } public object GetValue(int i) { return Values[i]; } public int GetValues(object[] values) { Fill(values); Array.Copy(values, Values, this.FieldCount); return this.FieldCount; } public object this[int i] { get { return Values[i]; } } 

Hope this helps.

+2
source share

This can help...

  //1. Create dataset var ds = new DataSet("A Dataset"); var table = ds.Tables.Add("A Table"); table.Columns.Add("Id", typeof(int)); table.Columns.Add("Description", typeof(string)); //2. Serialize as xml ds.WriteXml(@"C:\temp\dataset.xml"); //3. Go look at the xml file contents. //Your xml needs to be translated into this schema. //You will have to write this. (Boring transform work...) //Dataset deserialization does not work with arbitrary xml documuents. //4. Loading the xml file var ds2 = new DataSet(); ds2.ReadXml(@"C:\temp\dataset.xml"); //Suggestion. Investigate using LINQ-to-xml. It would be easier to //read the data from your xml schema. You could also load the Dataset tables row by row //using this type of approach //1. Load xml data into an XElement. var element = XElement.Parse(@"<resultset> <datarow> <datacol>Row 1 - Col 1</datacol> <datacol>Row 1 - Col 2</datacol> <datacol>Row 1 - Col 3</datacol> </datarow> </resultset> "); //2. Create a dataset ds = new DataSet("A Dataset"); table = ds.Tables.Add("A Table"); table.Columns.Add("Col1", typeof(string)); table.Columns.Add("Col2", typeof(string)); table.Columns.Add("Col3", typeof(string)); //3. Walk XElements and add rows to tables foreach (var row in element.Elements("datarow")) { var r = table.NewRow(); table.Rows.Add(r); int i = 0; foreach (var columnValue in row.Elements("datacol")) { r[i++] = columnValue.Value; } } 
0
source share

All Articles