Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Generic data fetch with IDataReader [modified]

Generic data fetch with IDataReader [modified]

Scheduled Pinned Locked Moved C#
businesssalesregexquestiondiscussion
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    RubensFarias
    wrote on last edited by
    #1

    Hi there, I'm looking for some advise for a generic data fetch pattern for IDataReader I'm working on, as follow:

    // main load
    using(GenericDataReader reader = new GenericDataReader(cm.ExecuteReader()))
    {
    while (reader.Read())
    {
    orders.Add(reader.Get<Order>()); // "GetList" pattern
    //return new Order(reader); // "Get" pattern
    }
    }

    // generic reader; interface implementation removed
    public class GenericDataReader : IDataReader
    {
    // ... \\

    public T Get<T>(string name)
    {
        int i = \_dataReader.GetOrdinal(name);
        if (\_dataReader.IsDBNull(i))
            return default(T);
        else
            return (T)\_dataReader.GetValue(i);
    }
    
    public T Get<T>() where T : ILoadable, new()
    {
        T entity = new T();
        entity.Load(this, false);
        return entity;
    }
    

    }

    // All business objects must implements this interface
    public interface ILoadable
    {
    void Load(GenericDataReader reader, bool deep);
    }

    // Sample business object
    class Order : ILoadable
    {
    int id;
    Customer customer; // Note
    DateTime orderDate;
    DateTime requiredDate;
    DateTime? shippedDate;
    List<OrderDetail> orderDetails;

    public Order(){ }
    
    public Order(GenericDataReader reader)
    {
        Load(reader, true);
    }
    
    #region ILoadable Members
    
    public void Load(GenericDataReader reader, bool deep)
    {
        id = reader.Get<int>("OrderID");
        customer = reader.Get<Customer>(); // Note
        orderDate = reader.Get<DateTime>("OrderDate");
        requiredDate = reader.Get<DateTime>("OrderRequiredDate");
        shippedDate = reader.Get<DateTime?>("OrderShippedDate");
        if (deep && reader.NextResult())
        {
            orderDetails = new List<OrderDetail>();
            while (reader.Read())
            {
                orderDetails.Add(reader.Get<OrderDetail>());
            }
        }
    }
    
    #endregion
    

    }

    What do you think? Are there any major drawback with this model I'm missing? Are there any more clever way to do that? I really appreciate your time reading this. As long we come to a conclusion I'll write an article for CP with that we learned about it. TIA, Rubens EDIT: Added formatting

    modified on Thursday, March 20, 2008 6:44 AM

    M 2 Replies Last reply
    0
    • R RubensFarias

      Hi there, I'm looking for some advise for a generic data fetch pattern for IDataReader I'm working on, as follow:

      // main load
      using(GenericDataReader reader = new GenericDataReader(cm.ExecuteReader()))
      {
      while (reader.Read())
      {
      orders.Add(reader.Get<Order>()); // "GetList" pattern
      //return new Order(reader); // "Get" pattern
      }
      }

      // generic reader; interface implementation removed
      public class GenericDataReader : IDataReader
      {
      // ... \\

      public T Get<T>(string name)
      {
          int i = \_dataReader.GetOrdinal(name);
          if (\_dataReader.IsDBNull(i))
              return default(T);
          else
              return (T)\_dataReader.GetValue(i);
      }
      
      public T Get<T>() where T : ILoadable, new()
      {
          T entity = new T();
          entity.Load(this, false);
          return entity;
      }
      

      }

      // All business objects must implements this interface
      public interface ILoadable
      {
      void Load(GenericDataReader reader, bool deep);
      }

      // Sample business object
      class Order : ILoadable
      {
      int id;
      Customer customer; // Note
      DateTime orderDate;
      DateTime requiredDate;
      DateTime? shippedDate;
      List<OrderDetail> orderDetails;

      public Order(){ }
      
      public Order(GenericDataReader reader)
      {
          Load(reader, true);
      }
      
      #region ILoadable Members
      
      public void Load(GenericDataReader reader, bool deep)
      {
          id = reader.Get<int>("OrderID");
          customer = reader.Get<Customer>(); // Note
          orderDate = reader.Get<DateTime>("OrderDate");
          requiredDate = reader.Get<DateTime>("OrderRequiredDate");
          shippedDate = reader.Get<DateTime?>("OrderShippedDate");
          if (deep && reader.NextResult())
          {
              orderDetails = new List<OrderDetail>();
              while (reader.Read())
              {
                  orderDetails.Add(reader.Get<OrderDetail>());
              }
          }
      }
      
      #endregion
      

      }

      What do you think? Are there any major drawback with this model I'm missing? Are there any more clever way to do that? I really appreciate your time reading this. As long we come to a conclusion I'll write an article for CP with that we learned about it. TIA, Rubens EDIT: Added formatting

      modified on Thursday, March 20, 2008 6:44 AM

      M Offline
      M Offline
      mmikey7
      wrote on last edited by
      #2

      Hi, can you please edit your post and place code in <pre> and <code> like this?: <pre><code>your code</code></pre> that would really help me to at least read your code. Thank you.

      R 1 Reply Last reply
      0
      • M mmikey7

        Hi, can you please edit your post and place code in <pre> and <code> like this?: <pre><code>your code</code></pre> that would really help me to at least read your code. Thank you.

        R Offline
        R Offline
        RubensFarias
        wrote on last edited by
        #3

        Sorry Michal, here you go. ty

        1 Reply Last reply
        0
        • R RubensFarias

          Hi there, I'm looking for some advise for a generic data fetch pattern for IDataReader I'm working on, as follow:

          // main load
          using(GenericDataReader reader = new GenericDataReader(cm.ExecuteReader()))
          {
          while (reader.Read())
          {
          orders.Add(reader.Get<Order>()); // "GetList" pattern
          //return new Order(reader); // "Get" pattern
          }
          }

          // generic reader; interface implementation removed
          public class GenericDataReader : IDataReader
          {
          // ... \\

          public T Get<T>(string name)
          {
              int i = \_dataReader.GetOrdinal(name);
              if (\_dataReader.IsDBNull(i))
                  return default(T);
              else
                  return (T)\_dataReader.GetValue(i);
          }
          
          public T Get<T>() where T : ILoadable, new()
          {
              T entity = new T();
              entity.Load(this, false);
              return entity;
          }
          

          }

          // All business objects must implements this interface
          public interface ILoadable
          {
          void Load(GenericDataReader reader, bool deep);
          }

          // Sample business object
          class Order : ILoadable
          {
          int id;
          Customer customer; // Note
          DateTime orderDate;
          DateTime requiredDate;
          DateTime? shippedDate;
          List<OrderDetail> orderDetails;

          public Order(){ }
          
          public Order(GenericDataReader reader)
          {
              Load(reader, true);
          }
          
          #region ILoadable Members
          
          public void Load(GenericDataReader reader, bool deep)
          {
              id = reader.Get<int>("OrderID");
              customer = reader.Get<Customer>(); // Note
              orderDate = reader.Get<DateTime>("OrderDate");
              requiredDate = reader.Get<DateTime>("OrderRequiredDate");
              shippedDate = reader.Get<DateTime?>("OrderShippedDate");
              if (deep && reader.NextResult())
              {
                  orderDetails = new List<OrderDetail>();
                  while (reader.Read())
                  {
                      orderDetails.Add(reader.Get<OrderDetail>());
                  }
              }
          }
          
          #endregion
          

          }

          What do you think? Are there any major drawback with this model I'm missing? Are there any more clever way to do that? I really appreciate your time reading this. As long we come to a conclusion I'll write an article for CP with that we learned about it. TIA, Rubens EDIT: Added formatting

          modified on Thursday, March 20, 2008 6:44 AM

          M Offline
          M Offline
          mmikey7
          wrote on last edited by
          #4

          I would consider two things. First would be performance of return (T)_dataReader.GetValue(i);, I don't know exactly how GetValue works internally but I think that it is a bit slower than type specific method like GetInt32 becase there is more type conversion stuff. Plus by using type specific Get method you would save one of your type conversion return **(T)**_dataReader.GetValue(i). Disadvantage is that you would have to use IF statement to determine which specific Get method to call. Second thought is that I'm not sure if it is a best practice to have GenericDataReader to create businness objects. In my opinion objects like data readers should just get you a data and that is it. They should not be creating any business objects. Also I think that Business object should not work directly with data reader. It has lot of other work to do anyway. So I would suggest to create some BusinessDataObject that would take care of getting data from database, using GenericDataReader. And then any business object would just use relevant BusinessDataObject to load data.

          R 1 Reply Last reply
          0
          • M mmikey7

            I would consider two things. First would be performance of return (T)_dataReader.GetValue(i);, I don't know exactly how GetValue works internally but I think that it is a bit slower than type specific method like GetInt32 becase there is more type conversion stuff. Plus by using type specific Get method you would save one of your type conversion return **(T)**_dataReader.GetValue(i). Disadvantage is that you would have to use IF statement to determine which specific Get method to call. Second thought is that I'm not sure if it is a best practice to have GenericDataReader to create businness objects. In my opinion objects like data readers should just get you a data and that is it. They should not be creating any business objects. Also I think that Business object should not work directly with data reader. It has lot of other work to do anyway. So I would suggest to create some BusinessDataObject that would take care of getting data from database, using GenericDataReader. And then any business object would just use relevant BusinessDataObject to load data.

            R Offline
            R Offline
            RubensFarias
            wrote on last edited by
            #5

            Looking at System.Data.OleDb implementation through Reflector, GetInt32 and GetValue returns values based on column types, so I think both have similar performance. And, if I had to code an IF inside that generic method, I prefer to stick with current ADO.NET implementation About your second thought, I share your feelings. My main point is to define a simple pattern for data fetch, probably in a structure like Entity (get/set/read) >> Data (DAL/.executeXXX) >> Business (work with loaded data) >> and so on. Thank you for your comments, I really appreciate them. Rubens

            M 1 Reply Last reply
            0
            • R RubensFarias

              Looking at System.Data.OleDb implementation through Reflector, GetInt32 and GetValue returns values based on column types, so I think both have similar performance. And, if I had to code an IF inside that generic method, I prefer to stick with current ADO.NET implementation About your second thought, I share your feelings. My main point is to define a simple pattern for data fetch, probably in a structure like Entity (get/set/read) >> Data (DAL/.executeXXX) >> Business (work with loaded data) >> and so on. Thank you for your comments, I really appreciate them. Rubens

              M Offline
              M Offline
              mmikey7
              wrote on last edited by
              #6

              regarding GetValue you may check this link[^]

              RubensFarias wrote:

              Thank you for your comments, I really appreciate them.

              You are welcome. Those are just my thoughts, that may be wrong. And practical solution is often far far away from ideal design. Important thing is to get things done. I wish you luck with your project.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups