none
DataSet in a 3-tier application with Model-View-Presenter RRS feed

  • Question

  • Hello,

    I have 2 classes in my DAL:

    Customer.cs and Order.cs a 1:Many relation.

    When I have 3 classes Customer,Order,Product where should I instantiate my Dataset so I can fill it with Data from each SqlDataAdapter ?

    var ds = new DataSet();

    dataAdapterCustomer.Fill(ds);
    dataAdapterOrder.Fill(ds);
    dataAdapterProducts.Fill(ds);

    Where should I do this? IN the Presenter? If yes what is the return type of these methods:

    CustomerDAO.cs
    public XXX GetCustomers(){}

    OrderDAO.cs
    public XXX GetOrders(){} 

    ...

    Is the return type a SqlDataAdapter?

    Or asked differently, when I have 10 tables I want to put them all in ONE DataSet and create Relations in Code how must my DAL + BLL look ?
    Friday, October 23, 2009 9:56 AM

Answers

  • thank you Bonnie for helping but your links did not solve my problem. I will try to explain again in other words.
    Well, it would if you restructured your DataAccess classes. ;0) I think my point was to show another way to handle DataAccess.

    Anyway, your DataAccess method shouldn't return the DataAdapter, it should return the DataSet that is filled by the DataAdapter.

    However, since in your case you are using separate classes for filling each type of table, you might want to do this a little differently (I'm assuming that you're not using Stored Procs ... a Stored Proc would make it a lot easier because it could return all three of your tables at once and fill your entire DataSet with only one call the DataAdpater.Fill() method).

    Anyway, given the way you've currently constructed things, I would instantiate the DataSet in the BLL, then pass that DataSet to each DAO method. Something like this:

    BLL
    MyDataSet ds = new MyDataSet();

    The above DataSet would be defined to contain your 3 DataTables, Customer, Order and Product.

    Then, your DataAccess classes and methods would look like this:

    CustomerDAO:
    public void GetCustomer(MyDataSet ds)
    {
        ...
       dataAdapterCustomer.Fill(ds, "Customer");
    }

    OrderDAO:
    public void GetOrder(MyDataSet ds)
    {
        ...
       dataAdapterOrder.Fill(ds, "Order");
    }

    And you'd call all this in your BLL like this:

    BLL
    MyDataSet ds = new MyDataSet();
    CustomerDAO.GetCustomer(ds);
    OrderDAO.GetOrder(ds);
    ProductDAO.GetProduct(ds);

    Does that help?

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Marked as answer by Yichun_Feng Thursday, October 29, 2009 1:27 AM
    Monday, October 26, 2009 5:50 PM

All replies

  • DAL should only contain DataAccess code. Period. Your BLL calls the methods in your DAL. I haven't used the Model-View-Presenter pattern, so I'm not sure what's contained in each (you know, where the BLL and DAL live) ... but your Form should have a call to the BLL method to retrieve the data. These methods return DataSets.

    Take a look at two blog posts I have written. I intend on writing one more on DataAccess, but haven't had the time to do it yet ... these two should either give you enough information to get you started down the right path, or at least get you thinking about asking other questions:

    http://geek-goddess-bonnie.blogspot.com/2009/09/dataaccess-part-i.html
    http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-ii.html
    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Edited by BonnieBMVP Saturday, November 7, 2009 12:58 AM fixed typo in blog link
    Friday, October 23, 2009 10:53 PM
  • thank you Bonnie for helping but your links did not solve my problem. I will try to explain again in other words.

    Lets say I have a DAL with 2 classes with a 1:M relationship Customer and Order.

    CustomerDAO.cs // here I connect to the database and get customer data
    in the GetCustomer() method:
    all data is put into a customerSqlDataAdapter

    what is the return type of the GetCustomer() method when I call the GetCustomer in my BLL like:


    DataType customerData = customerDAO.GetCustomer();

    1.) What is the DataType for a type?


    2.) Where to I declare my DataSet to take the data of the return value of customerData and orderData?

    OrderDAO.cs // here I connect to the database and get order data
    in the GetOrder() method:
    all data is put into a orderSqlDataAdapter

    ...

    Monday, October 26, 2009 8:38 AM
  • thank you Bonnie for helping but your links did not solve my problem. I will try to explain again in other words.
    Well, it would if you restructured your DataAccess classes. ;0) I think my point was to show another way to handle DataAccess.

    Anyway, your DataAccess method shouldn't return the DataAdapter, it should return the DataSet that is filled by the DataAdapter.

    However, since in your case you are using separate classes for filling each type of table, you might want to do this a little differently (I'm assuming that you're not using Stored Procs ... a Stored Proc would make it a lot easier because it could return all three of your tables at once and fill your entire DataSet with only one call the DataAdpater.Fill() method).

    Anyway, given the way you've currently constructed things, I would instantiate the DataSet in the BLL, then pass that DataSet to each DAO method. Something like this:

    BLL
    MyDataSet ds = new MyDataSet();

    The above DataSet would be defined to contain your 3 DataTables, Customer, Order and Product.

    Then, your DataAccess classes and methods would look like this:

    CustomerDAO:
    public void GetCustomer(MyDataSet ds)
    {
        ...
       dataAdapterCustomer.Fill(ds, "Customer");
    }

    OrderDAO:
    public void GetOrder(MyDataSet ds)
    {
        ...
       dataAdapterOrder.Fill(ds, "Order");
    }

    And you'd call all this in your BLL like this:

    BLL
    MyDataSet ds = new MyDataSet();
    CustomerDAO.GetCustomer(ds);
    OrderDAO.GetOrder(ds);
    ProductDAO.GetProduct(ds);

    Does that help?

    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    • Marked as answer by Yichun_Feng Thursday, October 29, 2009 1:27 AM
    Monday, October 26, 2009 5:50 PM
  • YESSH ;-) but is that best practice what I am always after? :)
    Friday, November 6, 2009 11:17 AM
  • What part of it do you question as best practice? Best practice, in my opinion, are the examples that have been posted on my blog (BTW, I added a Part III that you may want to look at also: http://geek-goddess-bonnie.blogspot.com/2009/10/dataaccess-part-iii.html).

    Personally, I would not have broken down the DataAccess as you did into 3 DataAccess classes, which then necessitated filling the DataSet with method calls to 3 different objects. While not optimal, it's certainly workable and probably ok.

    I think best practices would also constitute using Typed DataSets and Stored Procedures, which you have also not done.


    ~~Bonnie Berent [C# MVP]

    geek-goddess-bonnie.blogspot.com
    Saturday, November 7, 2009 12:57 AM