Click here to Skip to main content
15,914,066 members
Home / Discussions / C#
   

C#

 
GeneralRe: Multiple instances of FileSystemWatcher Pin
SatyaDY18-Jan-07 1:11
SatyaDY18-Jan-07 1:11 
AnswerRe: Multiple instances of FileSystemWatcher Pin
amitrajput28418-Jan-07 1:19
amitrajput28418-Jan-07 1:19 
Questionfinding average Pin
viru0417-Jan-07 21:25
viru0417-Jan-07 21:25 
AnswerRe: finding average Pin
Stefan Troschuetz17-Jan-07 21:32
Stefan Troschuetz17-Jan-07 21:32 
GeneralRe: finding average Pin
Russell Jones17-Jan-07 22:51
Russell Jones17-Jan-07 22:51 
QuestionBest Data Access Objects in .NET? Pin
Blumen17-Jan-07 21:08
Blumen17-Jan-07 21:08 
AnswerRe: Best Data Access Objects in .NET? Pin
il_masacratore17-Jan-07 22:07
il_masacratore17-Jan-07 22:07 
GeneralRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon17-Jan-07 23:27
mvePete O'Hanlon17-Jan-07 23:27 
il_masacratore wrote:
Thats my point of view. There're persons who prefer work with collections because they think that more easy to maintain...


Not easier to maintain, but easier to work with in an OO fashion. Here's a quick example:

public interface IValid
{
  bool IsValid { get ; }
}

public void ItemBase
{
   /// <summary>
   /// Ensure that the string cannot be longer than a certain length.
   /// A simplistic approach to preventing buffer overruns.
   /// </summary>
   protected virtual string TrimString(string value, maxLength)
   {
     if (value == null || value.Trim().Length == 0)
       return value;
     value = value.Trim();
     if (value.Length > maxLength)
     {
       value = value.Substring(0, maxLength)
     }
     return value;
   }
}

public void Customer : ItemBase, IValid
{
  private string _forename;
  private string _surname;

  public Customer(string forename, string surname)
  {
    _forename = TrimString(forename, 30);
    _surname = TrimString(surname, 30);
  }

  /// <summary>
  /// Get or set the forename.
  /// </summary>
  public string Forename
  {
    get { return _forename; }
    set { _forename = TrimString(value, 30); }
  }

  /// <summary>
  /// Get or set the surname.
  /// </summary>
  public string Surname
  {
    get { return _surname; }
    set { _surname = TrimString(value, 30); }
  }

  /// <summary>
  /// A <see cref="Customer"/> must have a forename before being saved.
  /// </summary>
  public bool IsValid
  {
    get
    {
      bool valid = false;
      if (_forename != null && _forename.Trim().Length > 0)
        valid = true;
      return valid;
    }
  }
}

public abstract class BaseCollection<T> where T : IValid
{
  private List<T> _list;

  /// <summary>
  /// A collection of objects of type <T>.
  /// </summary>
  public List<T> Collection
  {
    get { return _list ; }
    set { _list = value; }
  }

  /// <summary>
  /// Add object T to the collection if valid.
  /// </summary>
  public void Add(T value)
  {
    if (value.IsValid)
    {
      _list.Add(T);
    }
    else
    {
      // This exception would normally be much more explicit.
      // This is not a good example of an exception message, but
      // constraints in posting width kind of necessitate this.
      throw new Exception("Invalid object.");
    }
  }
  /// <summary>
  /// Fill the collection from the datastore.
  /// </summary>
  public abstract void Fill();

  /// <summary>
  /// This method must be implemented to physically add the item to the
  /// collection. The values will be read out of the datareader and then
  /// added to the collection.
  /// </summary>
  protected abstract void AddRow(IDataReader dr);

  /// <summary>
  /// This method should be called from the <see cref="Fill" /> method
  /// to ensure that the collection is filled.
  /// </summary>
  protected void Add(IDataReader dr)
  {
    if (dr.HasRows)
    {
      while (dr.Read())
      {
        AddRow(dr);
      }
    }
  }

}

public class Customers : BaseCollection<Customer>
{
  /// <summary>
  /// Method to add fill the Customers collection.
  /// </summary>
  public override void Fill()
  {
    // Call the database and get a DataReader to fill the base
    // collection.
    using (SqlConnection conn = new SqlConnection(Utilities.ConnectionString))
    {
      using (SqlCommand cmd = new SqlCommand())
      {
        cmd.Connection = conn;
        cmd.CommandText = "GetAllCustomers";
        cmd.CommandType = CommandType.StoredProcedure;
        conn.Open();
        using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
        {
           Add(dr);
        }
      }
    }
  }

  /// <summary>
  /// Add the customer information from the datareader into the collection.
  /// </summary>
  protected override void AddRow(IDataReader dr)
  {
    string forename = dr.GetString(dr.GetOrdinal("forename"));
    string surname = dr.GetString(dr.GetOrdinal("surname"));

    try
    {
      Add(new Customer(forename, surname));
    }
    catch (Exception ex)
    {
      Console.WriteLine(ex.Message);
    }
  }
}

Notice that you only have to implement the two methods in the inherited collection class to get the benefits of adding data from the database into your collection. It is trivial to extend this functionality to include the ability to search for records, save or delete them. Now, your client code will be a lot easier. Which of these do you think is easier to use?

customer.Surname = "Smith";


or

ds.Tables[0].Rows[0]["surname"] = "Smith";


What happens when you change the field name in the database from surname to cust_surname. In the implementation above, you only need to change this reference in the Customers class. If you are using a DataSet, then you have to hunt them down in every location that they are referred to and you could well end up missing them. Plus, what happens if you've exposed this as a web-service? The DataSet is a Microsoft implementation, so if a Java application is going to consume the DataSet then they are going to have to wrap up a heavy duty object. Plus, the renaming problem becomes much worse if you have changed the name of the column in the database. You are now asking everybody who consumes your DataSet to change their references to the field name. By the way, you can still bind the Collection property to items like a datagrid because this is a collection class.

I know that the abstraction seems to be a complete PITA, but once you have created a base object that you are happy with, you can easily reuse (and extend) this functionality. With the use of a tool like CodeSmith, creating the other classes becomes trivial.




the last thing I want to see is some pasty-faced geek with skin so pale that it's almost translucent trying to bump parts with a partner - John Simmons / outlaw programmer

Deja View - the feeling that you've seen this post before.

GeneralRe: Best Data Access Objects in .NET? Pin
il_masacratore17-Jan-07 23:41
il_masacratore17-Jan-07 23:41 
GeneralRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon17-Jan-07 23:55
mvePete O'Hanlon17-Jan-07 23:55 
GeneralRe: Best Data Access Objects in .NET? Pin
il_masacratore18-Jan-07 0:04
il_masacratore18-Jan-07 0:04 
GeneralRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon18-Jan-07 0:09
mvePete O'Hanlon18-Jan-07 0:09 
GeneralRe: Best Data Access Objects in .NET? Pin
il_masacratore18-Jan-07 0:28
il_masacratore18-Jan-07 0:28 
AnswerRe: Best Data Access Objects in .NET? Pin
Guffa18-Jan-07 1:18
Guffa18-Jan-07 1:18 
QuestionRe: Best Data Access Objects in .NET? Pin
Blumen18-Jan-07 6:10
Blumen18-Jan-07 6:10 
AnswerRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon18-Jan-07 8:38
mvePete O'Hanlon18-Jan-07 8:38 
GeneralRe: Best Data Access Objects in .NET? Pin
Blumen19-Jan-07 5:45
Blumen19-Jan-07 5:45 
GeneralRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon19-Jan-07 10:28
mvePete O'Hanlon19-Jan-07 10:28 
QuestionRe: Best Data Access Objects in .NET? Pin
Blumen20-Jan-07 7:37
Blumen20-Jan-07 7:37 
AnswerRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon20-Jan-07 8:11
mvePete O'Hanlon20-Jan-07 8:11 
GeneralRe: Best Data Access Objects in .NET? Pin
Blumen20-Jan-07 22:14
Blumen20-Jan-07 22:14 
GeneralRe: Best Data Access Objects in .NET? Pin
Pete O'Hanlon21-Jan-07 9:05
mvePete O'Hanlon21-Jan-07 9:05 
GeneralRe: Best Data Access Objects in .NET? Pin
Blumen21-Jan-07 15:36
Blumen21-Jan-07 15:36 
Questionobject does(n't) exist? Pin
V.17-Jan-07 21:07
professionalV.17-Jan-07 21:07 
Questionsave dataview as a Excel file [modified] Pin
teymur_khan17-Jan-07 20:49
teymur_khan17-Jan-07 20:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.