DAL and BLL with Lazy Loading - lazy-loading

How would one implement lazy loading in the context of three tiers? I understand the basic architecture of Presentation Layer, Business Layer, and Data Layer:
You have your basic "dumb" classes that are nearly mirror images of the tables in the database with one exception. Instead of foreign key IDs you have a reference to the actual instance(s) of what is being referred to. For example: Employee with Name/DOB/Title properties.
Then for each of these classes you have a class that provides the CRUD operations on it plus any custom data storage routines you might need (calling a stored procedure that works with that object, etc). This class would be swapped out if you changed database. For example: EmployeeDAL.Save(myEmployee), EmployeeDAL.Get(myEmployee) (where myEmployee has their ID populated but nothing else)
You have business layer classes that perform validation and what not. The methods in these classes usually end by calling into the DAL to persist information or to retrieve it. This is changed when the customer changes their mind about what constitutes valid/invalid data or wants to change the way some calculation is done.
The presentation layer interacts with the business layer to display things and shuttle inserts/updates made in the UI to the lower layers. For example: it loops over a list of Employees and displays them in an HTML table.
But where exactly would the code for lazy loading references go? If the presentation layer has a Company object that it just displayed and is beginning the process of displaying myCompany.Employees, how is that achieved? myCompany is an instance of one of the dumb classes that mirror the database tables and isn't supposed to know about how to retrieve anything.
Do you do as the answer to this question suggests and create a Dummy version of each object? Then the DAL level object can have variables indicating if Employees has or has not been loaded and call DALEmployee.GetEmployees(this)? I feel as if I'm missing something crucial about the pattern...

If you use a pre-built framework such as nHibernate this will make it all much easier, you can define the lazy-loading in the class/table mapping and when a query is run. To do it yourself in a neat manner is going to take a fair bit of code although the System.Lazy class in .NET 4 may help.

Related

Strategy for Sharing Business and Data Access Entities

I'm designing a layered application where 90% of the business and data access entities have the same properties. Basically it doesn't make sense to create one set of classes for each layer (and map) with the same properties for the sake of separation of concerns. I'm completely aware of automappers but I'd rather not use one in this case as I think it's unecessary. Is it ok to share share the business entities between the business and data access layer in this scenario? We will manage the remaining 10% of the classes by creating adhoc/transformed classes within the same namespace.
Any other design approach?
I think sharing between layers is the whole point of having model classes backed by a data store. I would avoid adding unnecessary architecture unless the code really needs it. If you get to a point where you need to be agnostic of the data store or some other similar situation, I would you might look into the Repository pattern. Simple code = maintainable code.

Does adding PetaPoco attributes to POCO's have any negative side effects?

Our current application uses a smart object style for working with the database. We are looking at the feasibility of moving to PetaPoco instead. Looking over the features I notice you can add attributes to make it easier to CRUD objects. Does adding these attributes have any negative side effects that I should be aware of?
Has anyone found a reason NOT to use these decorators?
Directly to the use of the POCO object instance itself? None.
At least not that I would be aware of. Jon Skeet should be able to provide more info because he knows compiler inner workings through and through, so he knows exactly what happens with this metadata after it's been compiled.
Other implications indirectly related to these
There are of course implications when accessing these declarative attributes, because they're read using reflection which is normally a slow process.
But there's nothing to worry here, because PetaPoco is a smart library and reads these only once then compiles & caches these things, so you only get penalized once then you get blazing performance afterwards. Because it uses compiled code.
Non-performance related implications
By putting attributes (any) on your classes/properties/methods you somehow bind your code to particular engine that will use this class, because they're directives for this particular engine to understand your code.
In case of PetaPoco attributes this means that your class can be used with PetaPoco but not with some other DAL (ie. EF) unless you add attributes of that one as well (EF Code First uses the very same approach with attributes).
The second implication is related to back-end database. In case you rename a table, column or any other part that is provided in your PetaPoco attribute as a constant magic string, you will subsequently have to change this string as well. This just means that you have to be thorough when doing database changes...
One downside is that it breaks the separation between the "domain" layer and the "data" layer, since it introduces the PetaPoco file (which contains data logic) to domain classes that should really not have any knowledge or dependency on the data layer.
If you're doing a single-project MVC app or something then it's okay to just use the Models directory for both, but for non-trivial and separated apps you'll have to have two PetaPoco files or play around with abstracting portions of the file in order to annotate your models without making them "know too much" about the underlying data, or else have you specify the table and/or primary key name all over the place.

yii and non database models

I need some help as I seem not to be able to grasp the concept.
In a framework, namely Yii, we create models that correspond to database tables. We extend them from CActiveRecord.
However, if I want to create a class that will get some data from other models but then will do all the computations based on those results and do something with them... then how do I proceed?
I want to clearly divide the responsibility so I don't want put all the calculations in source db based models. Basically the idea is that it will be taking some stuff from some models and then updating another models with the results of the calculations.
What do I do?
Keep all the calculations in some controller and use required models? (Hesitant about this because there is a rule to keep controller slim)
Create a none db model and then work from there (how?)?
Do something else (what?)?
Thanks for any help!
For you to use the Yii interpretation of Model, you will have to create class, which depends on CModel. It is an abstract class, thus you will be required to implement attributeNames() method.
To use other "Models" with this new structure, you will need to inject them in constructor, or right after your custom model has been created.
In real MVC model is a layer, which mostly contains two sets of classes with specific responsibilities: domain business logic and data access operations. Objects which are responsible for Domain Business Logic have no clue where the information is stored and where it comes from. Or even if there is such a thing as "database".
This video might explain a bit: https://vimeo.com/21173483

How can I gradually transition to NHibernate persistence logic from existing ADO.NET persistence logic?

The application uses ADO.NET to invoke sprocs for nearly every database operation. Some of these sprocs also contain a fair amount of domain logic. The data access logic for each domain entity resides in the domain class itself. ie, there is no decoupling between domain logic and data access logic.
I'm looking to accomplish the following:
decouple the domain logic from the data access logic
make the domain model persistence ignorant
implement the transition to NHibernate gradually across releases, refactoring individual portions of the DAL (if you can call it that) at a time
Here's my approach for transitioning a single class to NHibernate persistence
create a mapping for the domain class
create a repository for the domain class (basic CRUD operations inherited from a generic base repository)
create a method in the repository for each sproc used by the old DAL (doing some refactoring along the way to pull out the domain logic)
modify consumers to use the repository rather than the data access logic in the class itself
remove the old data access logic and the sprocs
The issues I have are with #1 and #4.
(#1) How can I map properties of a type with no NHibernate mapping?
Consider a Person class with an Address property (Address being a domain object without an NH mapping and Person being the class I'm mapping). How can I include Address in the Person mapping without creating an entire mapping for Address?
(#4) How should I manage the dependencies on old data access logic during the transition?
Classes in the domain model utilize the old data access logic that I'm looking to remove. Consider an Order class with a CustomerId property. When the Order needs info on the Customer it invokes the ADO.NET data access logic that resides in the Customer class. What options are there other than maintaining the old data access logic until the dependent classes are mapped themselves?
I would approach it like this:
Refactor and move the data access logic out of the domain classes into a data layer.
Refactor and move the domain logic out of the sprocs into a data layer. (This step is optional, but doing it will definitely make the transition smoother and easier.)
You don't need a repository, but you can certainly create one if you want.
Create a NHibernate mapping for every domain class (there are tools that do this).
Create a NHibernate oriented data access API that slowly replaces the sproc data layer.
Steps 1 & 2 are the hardest part as it sounds like you have tight coupling that ideally never would have happened. Neither of these first two steps involve NHibernate at all. You are strictly moving to a more maintainable architecture before trying to swap out your data layer.
While it may be possible to create NHibernate mappings one by one and utilize them without the full object graph being available, that seems like asking for unnecessary pain. You need to proceed very cautiously if you choose that path and I just wouldn't recommend it. To do so, you may leave a foreign key mapped as a plain int/guid instead of as a relation to another domain class, but you have to be very careful you don't corrupt your data by half committing to NHibernate in that way. Automated unit/integration tests are your friend.
Swapping out a data layer is hard. It is easier if you have a solid lowest common denominator data layer architecture, but I wouldn't actually recommend creating an architecture using a lowest common denominator approach. Loose coupling is good, but you can go too far.
search more on the internet for nhibernate e-books
Refactor and move the data access logic out of the domain classes into a data layer.
Refactor and move the domain logic out of the sprocs into a data layer. (This step is optional, but doing it will definitely make the transition smoother and easier.)
You don't need a repository, but you can certainly create one if you want.
Create a NHibernate mapping for every domain class (there are tools that do this).
Create a NHibernate oriented data access API that slowly replaces the sproc data layer

Should entities have behavior or not?

Should entities have behavior? or not?
Why or why not?
If not, does that violate Encapsulation?
If your entities do not have behavior, then you are not writing object-oriented code. If everything is done with getters and setters and no other behavior, you're writing procedural code.
A lot of shops say they're practicing SOA when they keep their entities dumb. Their justification is that the data structure rarely changes, but the business logic does. This is a fallacy. There are plenty of patterns to deal with this problem, and they don't involve reducing everything to bags of getters and setters.
Entities should not have behavior. They represent data and data itself is passive.
I am currently working on a legacy project that has included behavior in entities and it is a nightmare, code that no one wants to touch.
You can read more on my blog post: Object-Oriented Anti-Pattern - Data Objects with Behavior .
[Preview] Object-Oriented Anti-Pattern - Data Objects with Behavior:
Attributes and Behavior
Objects are made up of attributes and behavior but Data Objects by definition represent only data and hence can have only attributes. Books, Movies, Files, even IO Streams do not have behavior. A book has a title but it does not know how to read. A movie has actors but it does not know how to play. A file has content but it does not know how to delete. A stream has content but it does not know how to open/close or stop. These are all examples of Data Objects that have attributes but do not have behavior. As such, they should be treated as dumb data objects and we as software engineers should not force behavior upon them.
Passing Around Data Instead of Behavior
Data Objects are moved around through different execution environments but behavior should be encapsulated and is usually pertinent only to one environment. In any application data is passed around, parsed, manipulated, persisted, retrieved, serialized, deserialized, and so on. An entity for example usually passes from the hibernate layer, to the service layer, to the frontend layer, and back again. In a distributed system it might pass through several pipes, queues, caches and end up in a new execution context. Attributes can apply to all three layers, but particular behavior such as save, parse, serialize only make sense in individual layers. Therefore, adding behavior to data objects violates encapsulation, modularization and even security principles.
Code written like this:
book.Write();
book.Print();
book.Publish();
book.Buy();
book.Open();
book.Read();
book.Highlight();
book.Bookmark();
book.GetRelatedBooks();
can be refactored like so:
Book book = author.WriteBook();
printer.Print(book);
publisher.Publish(book);
customer.Buy(book);
reader = new BookReader();
reader.Open(Book);
reader.Read();
reader.Highlight();
reader.Bookmark();
librarian.GetRelatedBooks(book);
What a difference natural object-oriented modeling can make! We went from a single monstrous Book class to six separate classes, each of them responsible for their own individual behavior.
This makes the code:
easier to read and understand because it is more natural
easier to update because the functionality is contained in smaller encapsulated classes
more flexible because we can easily substitute one or more of the six individual classes with overridden versions.
easier to test because the functionality is separated, and easier to mock
It depends on what kind of entity they are -- but the term "entity" implies, to me at least, business entities, in which case they should have behavior.
A "Business Entity" is a modeling of a real world object, and it should encapsulate all of the business logic (behavior) and properties/data that the object representation has in the context of your software.
If you're strictly following MVC, your model (entities) won't have any inherent behavior. I do however include whatever helper methods allow the easiest management of the entities persistence, including methods that help with maintaining its relationship to other entities.
If you plan on exposing your entities to the world, you're better off (generally) keeping behavior off of the entity. If you want to centralize your business operations (i.e. ValidateVendorOrder) you wouldn't want the Order to have an IsValid() method that runs some logic to validate itself. You don't want that code running on a client (what if they fudge it. i.e. akin to not providing any client UI to set the price on an item being placed in a shopping cart, but posting a a bogus price on the URL. If you don't have server-side validation, that's not good! And duplicating that validation is...redundant...DRY (Don't Repeat Yourself).
Another example of when having behaviors on an entity just doesn't work is the notion of lazy loading. Alot of ORMs today will allow you to lazy load data when a property is accessed on an entities. If you're building a 3-tier app, this just doesn't work as your client will ultimately inadvertantly try to make database calls when accessing properties.
These are my off-the-top-of-my-head arguments for keeping behavior off of entities.