DAL Pattern Question

Last post 03-29-2008 1:57 PM by scott@elbandit.co.uk. 20 replies.

Sort Posts:

  • DAL Pattern Question

    01-30-2008, 9:22 AM
    • Loading...
    • nberardi
    • Joined on 06-14-2002, 4:58 AM
    • Phoenixville, PA
    • Posts 2,352

    This may seem like an odd question but bare with me.

    How do you fill the same data at varying degrees with the least amount of objects?

    For instance to the left of this post you see a small representation of my "User Object" that shows only the most basic information.  However when you click my user name you go in to my profile which contains this information plus some.  So assuming that ASP.NET Forums uses the same "User Object" for both of these different views of the same model and only fills the appropriate information when requested.  How would you go about programming this?  And is there currently a pattern or model that gets me almost there?

    Nick
     

    View My Blog Download My URL Rewriter and Reverse Proxy

    Only $9.95/month, ASP.NET, 2GB & SQL 2005
  • Re: DAL Pattern Question

    01-30-2008, 9:40 AM
    • Loading...
    • TATWORTH
    • Joined on 02-04-2003, 8:34 AM
    • England
    • Posts 7,031

    >So assuming that ASP.NET Forums uses the same "User Object" for both of these different views of the same model and only fills the appropriate information when requested

    Somewhat unlikely - I would expect different objects for each in oder to maximise speed.

    Don't forget to click "Mark as Answer" on the post that helped you.
    This credits that member, earns you a point and marks your thread as Resolved so we will all know you have been helped.
  • Re: DAL Pattern Question

    01-30-2008, 10:13 AM
    • Loading...
    • ParrotBoy
    • Joined on 10-08-2003, 5:56 AM
    • England
    • Posts 471

    I agree, it would be very unlikely to have an object that loads in data as it is requested as it would inevitably be slower than just loading all the data at once. I generate all my business entities using codesmith templates and in general I will have an object which allows updates and loads all the information for each table and a read-only object for each view. This way I could create a view named "SimpleUserInfo" for use in places like the right hand of this page, but if I wanted to update a User I would have to use the full-featured User object.
     

    Please mark posts as the answer if I was helpful. Thanks!

    Visit my blog
  • Re: DAL Pattern Question

    01-30-2008, 10:33 AM
    • Loading...
    • TATWORTH
    • Joined on 02-04-2003, 8:34 AM
    • England
    • Posts 7,031

     There a very cases where a lazy load feature is either require or desirable. I can only think of one project in 5 years of Dot Net that needed it.

    Don't forget to click "Mark as Answer" on the post that helped you.
    This credits that member, earns you a point and marks your thread as Resolved so we will all know you have been helped.
  • Re: DAL Pattern Question

    01-30-2008, 10:44 AM
    • Loading...
    • ParrotBoy
    • Joined on 10-08-2003, 5:56 AM
    • England
    • Posts 471

    TATWORTH:

     There a very cases where a lazy load feature is either require or desirable. I can only think of one project in 5 years of Dot Net that needed it.

     

    I assume that this was an object which loaded data from many different locations? 

    Please mark posts as the answer if I was helpful. Thanks!

    Visit my blog
  • Re: DAL Pattern Question

    01-30-2008, 11:11 AM
    • Loading...
    • TATWORTH
    • Joined on 02-04-2003, 8:34 AM
    • England
    • Posts 7,031

     >I assume that this was an object which loaded data from many different locations?

    A very astute assumption, however in this particular case it was a single SQL2000 database row and one column was a large text datatype, so this was only loaded on demand as the load took 1-2 seconds instead of being sub-second for the other values. In the general case, however you are perfectly correct. (Strictly speaking you are correct insofar as SQL 2000 will store large text values separately from the rest of the row.)

    Don't forget to click "Mark as Answer" on the post that helped you.
    This credits that member, earns you a point and marks your thread as Resolved so we will all know you have been helped.
  • Re: DAL Pattern Question

    01-30-2008, 5:49 PM

    I have used lazy-loading a little in the past and I use deep-loading often. It's really useful if you have a large object-model with alot of relationships that aren't always necessary. NetTiers handles deep-loading fairly well (with a patch applied to stop stack overflow exceptions) - you can pass in an object and specify the types that you wish to deepload.

    eg.

    User usr = UserService.GetById(1);

    UserService.DeepLoad(usr, typeof(Address));

    Address userAddress = usr.AddressSource;

     

  • Re: DAL Pattern Question

    01-30-2008, 10:28 PM
    • Loading...
    • nberardi
    • Joined on 06-14-2002, 4:58 AM
    • Phoenixville, PA
    • Posts 2,352

    ParrotBoy:

    I agree, it would be very unlikely to have an object that loads in data as it is requested as it would inevitably be slower than just loading all the data at once. I generate all my business entities using codesmith templates and in general I will have an object which allows updates and loads all the information for each table and a read-only object for each view. This way I could create a view named "SimpleUserInfo" for use in places like the right hand of this page, but if I wanted to update a User I would have to use the full-featured User object.

     

    I think I actually gave you guys the wrong impression.  My question wasn't about lazy loading each property individually.  I already know the performance problems with that.

    My question was essentially in creating a couples states of the object.  For example:

    // small fill
    User user1 = new User();
    user1.Id = (int)reader["Id"];
    user1.UserName = (string)reader["UserName"];
    
    // partially filled
    User user2 = new User();
    user2.Id = (int)reader["Id"];
    user2.UserName = (string)reader["UserName"];
    user2.LastPost = (DateTime)reader["LastPost"];
    
    // fully filled
    User user3 = new User();
    user3.Id = (int)reader["Id"];
    user3.UserName = (string)reader["UserName"];
    user3.LastPost = (DateTime)reader["LastPost"];
    user3.PostCount = (int)reader["PostCount"];
    user3.JoinedOn = (DateTime)reader["JoinedOn"];
    // etc...

    So my question is this.  Is there a better method or pattern that accomplishes something like this for the 3 different states of the User object above.  I have already determined that I don't want to create a separate object for each state of this object.  And performance is really important so minimizing the database calls and the data returned is very important.  The DAL doesn't have to be enterprise grade pattern or practice, because this is a Web 2.0 initiative where most of the objects requested are going to be the smaller objects that only have a limited amount of data.  And there are only a handful of them with very minor reliance on each other.

    Please let me know if you have any suggestions. 

    View My Blog Download My URL Rewriter and Reverse Proxy

    Only $9.95/month, ASP.NET, 2GB & SQL 2005
  • Re: DAL Pattern Question

    01-30-2008, 11:46 PM

    I'm not totally getting why you'd want to partially fill an object, leaving some properties null or default values. There's no point having an object and just not setting the properties. It won't save much in terms of performance and it'll make the object more difficult to work with (think NullReference Exceptions and default values mingled in with your real data...).

    I would use inheritance, and create SmallUser, PartialUser : SmallUser and a User:PartialUser classes. Although you mention that you don't want to create seperate classes for each. That would save some performance by excluding the stuff you don't want completely from the class.

    You could create 3 seperate interfaces - ISmallUser, IPartialUser : ISmallUser, IUser : IPartialUser with the appropriate public properties on them and have the User class implement IUser. By passing the appropriate interface around instead of the actual User class you could avoid accessing something you're not supposed to with that particular type of 'filledness' of the class. You still wouldn't be saving much in terms of performance but it would make a partially filled User object easier to work with (by programming against the appropriate interface and knowing exactly what you're dealing with instead of encountering a whole bunch of default value properties and NullReference Exceptions).

  • Re: DAL Pattern Question

    01-31-2008, 5:54 PM
    • Loading...
    • nberardi
    • Joined on 06-14-2002, 4:58 AM
    • Phoenixville, PA
    • Posts 2,352

    Mercury082:

    You could create 3 seperate interfaces - ISmallUser, IPartialUser : ISmallUser, IUser : IPartialUser with the appropriate public properties on them and have the User class implement IUser. By passing the appropriate interface around instead of the actual User class you could avoid accessing something you're not supposed to with that particular type of 'filledness' of the class. You still wouldn't be saving much in terms of performance but it would make a partially filled User object easier to work with (by programming against the appropriate interface and knowing exactly what you're dealing with instead of encountering a whole bunch of default value properties and NullReference Exceptions).

     

    Honestly the above was an example.  The actuality of what we are talking about is the same object one with 3 fields and the other with about 20 fields and a couple supporting collections pulled from another table.  So there is a real performance hit if I just need the three columns.  However most if not all of the methods in this object require the 3 fields in the smaller of the two data results, so it would be a pain to try and dual code for two different objects.  We considered an interface and coding two objects and a supporting state class with all the methods.  But that seemed clunky at best.

    We actually considered the interface option and it is still on the plate of possible solutions and seems like the best idea for now given the different views we need of the object.

    Really I was just looking for a sanity check in this forum.
     

    View My Blog Download My URL Rewriter and Reverse Proxy

    Only $9.95/month, ASP.NET, 2GB & SQL 2005
  • Re: DAL Pattern Question

    01-31-2008, 7:56 PM
    • Loading...
    • officialboss
    • Joined on 09-13-2006, 8:15 PM
    • California
    • Posts 153

    This is an interesting topic that I have been also wondering about. Could you post what solution you decided to go with and your reasons for doing so when you are done.

    Thanks

    Please be sure to click "Mark as Answer" on the post that helped you.
  • Re: DAL Pattern Question

    02-01-2008, 9:10 AM
    • Loading...
    • czuvich
    • Joined on 01-25-2007, 7:02 PM
    • Posts 261

    Same here. I'd like to know a solid pattern for this problem as well. My guess would be it depends... I like the solution posted above about loading the object all at once and then moving out what you need to a readonly object, but due to the 1-M relationships and other fields, you could suffer a performance hit.

    I've always been under the impression if you do it as posted above, your code is simple and easy to maintain; however, you suffer a performance hit. Whereas if you decide to load only what you need into particular objects, then you end up with more data access code; however, I would probably shy away from blank or null values in your objects.

  • Re: DAL Pattern Question

    02-02-2008, 5:24 PM
    • Loading...
    • nberardi
    • Joined on 06-14-2002, 4:58 AM
    • Phoenixville, PA
    • Posts 2,352
    I originally arrived at this pattern after reading up on the MVC (Model View Controller).  The idea of a model really intrigued me.  Because the more I thought about standard web pages they are mostly based around only one "object", such as a User or a Product and everything else is just meta data, such as purchases for the User.  So if you define all your models that you need for your website ahead of time such as User, UserProfile, Product, ProductProfile, etc you have not only helped define a development plan, but you have created very convent interfaces that both have common attributes.  For example: 
    interface IUser {
        int Id { get; set; }
        string UserName { get; set; }
        DateTime JoinedOn { get; set; }
    }
    
    interface IUserProfile : IUser {
        string FullName { get; set; }
        string Email { get; set; }
        UserBilling Billing { get; set; }
        Address Address { get; set; }
        List Purchases { get; }
    
        void MakePurchase(IProduct product);
    }
    
    interface IProduct {
        int Id { get; set; }
        string Name { get; set; }
        decimal Price { get; set; }
        string Description { get; set; }
    }
    
    interface IProductProfile : IProduct {
        List<string> Comments { get; }
        float CustomerRating { get; set; }
        int StockCount { get; set; }
    
        void Purchase(IUser user);
        void AddPicture (string path);
    }
    Then with these interfaces you create objects. 
    class User : IUser, IUserProfile {
        // implement interfaces plus supporting code
    }
    
    class Product : IProduct, IProductProfile {
        // implement interfaces plus supporting code
    }
    Then you create a helper class to fill these methods in the data layer. 
    static class DataHelper {
    public static IProduct GetProduct (int id) {
    IProduct p = new Product();
    // get data from database and only fill in IProduct interfaces } public static IProductProfile GetProductProfile (int id) {
    IProductProfile p = new Product();
    // get data from database and fill in IProductProfile interfaces
    // including supporting tables such as the collections
    // or fill in some and dirty fill the others
    } // do the same for User }
    Personally this is similar to how I am now implementing it.  I am hoping LINQ is going to be able to help me out so that only the data I need is returned for each interface.  If LINQ can't do the job I may have to pony up the time and create the DAL by hand.  Honestly performance matters so I can't trust a DataSet in this instance.
    View My Blog Download My URL Rewriter and Reverse Proxy

    Only $9.95/month, ASP.NET, 2GB & SQL 2005
  • Re: DAL Pattern Question

    02-03-2008, 8:45 PM
    • Loading...
    • alibaba199
    • Joined on 01-28-2008, 8:27 AM
    • Posts 6

    If you want to maintain a high level of data/code integrity, you really should create separate BLL objects that reference the appropriate procs in your DAL.

    Otherwise, I would think you could do a quick & dirty implementation by giving the object a "state" variable which is set to x, y, or z when calling the proc to load x, y, or z set of data. Then, you'd have to confuse things by making a rule that when state=x, only set x of data is valid for the object. You could enforce this (and help your debugging) by overriding the objects' instance variable "get" (tired, can't remember the academic name) functions to return nulls if the data isn't valid in the current state.

    At least, that's what my overly tired brain is coming up with at the moment....

    Cheers

  • Re: DAL Pattern Question

    02-05-2008, 9:21 AM