Data Mapper Pattern - datamapper

Up until now I've been using Active records in all my c# database driven applications. But now my application requires my persistence code being split from my business objects. I have read a lot of posts regarding Martin Fowler's data mapping pattern, but my knowledge of this pattern is still very limited.
Let's use the following example:
If I have 2 tables - Customer and CustomerParameters. The CustomerParameters table contains default Customer values for creating a new Customer.
I will then have to create a CustomersMapper class to handle all of the Customer persistence. My Customer and CustomersList class will then collaborate with this mapper class in order to persist customer data.
I have the following questions:
How would I transfer raw data TO & FROM my Customer class to the mapper without breaking certain business rules? DTO's?
Is it acceptable to have a SaveAll and LoadAll method in my Mapper class for updating and loading multiple customers' data? If so, in case of SaveAll, how will the mapper know when to update or insert data?
Will the Customer mapper class be responsible for retrieving the default values from the CustomerParameters table as well, or will it be better to create a CustomerParameters mapper?
A O/R mapper tool is not really here. The database I'm using is Transactional and requires that I write my own Mapper Pattern.
Any ideas and comments will be greatly appreciated.

Shaun I would answer your questions this way:
ad 1) Mapper is responsible for creating Customer object. Your Mapper object will have something like RetrieveById method (for example). It will accept an ID and somehow (that't he responsibility of the Mapper object) construct the valid Customer object. The same is true the other way. When you call Mapper.Update method with a valid Customer object, the Mapper object is responsible for making sure that all the relevant data are persisted (wherever appropriate - db, memory, file, etc.)
ad 2) As I noted above retrieve/persist are methods on Mapper object. It is its responsibility to provide such a functionality. Therefore LoadAll, SaveAll (probably passing an array of value objects) are valid Mapper methods.
ad 3) I would say yes. But you can separate various aspects of Mapper objects into separate classes (if you want to/need to): default values, rule validation, etc.
I hope it helps. I really suggest/recommend you to read Martin Fowler's book Patterns of Enterprise Application Architecture.

I would suggest that you take a look at an O/R-mapper tool before you try to implement the Data Mapper pattern yourself. It will save you a lot of time. A popular choice of O/R-mapper is NHibernate.

You could check out iBATIS.NET as an alternative to NHibernate. It's also an O/R tool, but I've found it to be a little easier to use than NHibernate.
http://ibatis.apache.org/

Related

Entity Framework 4.1 and T4 class generation. Is this design overkill?

I am trying to get some design validation on modeling a domain using EF4.1 and T4.
At design time I run a customized a T4 poco generator template that reads edmx and creates 3 partial classes:
1) domain-level class (where any specific business methods will reside). this is only generated one time. Once Gen'd it's owned.
2) poco class just properties and virtual navigation properties to related objects, loaded lazily. this can be regen'ed if/when any underlying columns in the database change.
3) metadata class with an internal class whose properties are decorated with data annotations to provide additional column-level validation before inserting / updating data.
Is this overkill? I liked the separation, namely between the poco and domain object so that I can add methods to the partial domain object at any time without having to worry about method loss when needing to rerun the T4 template after underlying data specs may change. What about the metadata class? Is that unnecessary if my application will be performing field validation?

does linq-to-sql entity serialization work out of the box?

If I try to serialize a linq-to-sql entity, will it by default serialize only the primitive fields or will it try to access the relationship fields as well? If it tries to grab relationship fields, is there a way to override this?
Which serializer are you using?
The DataContractSerializer will
include loaded relationships but not
those that are not yet loaded / null.
The XmlSerializer tend to choke on relationships if they are bidirectional (i.e. entity A points to entity B which in turn points back).
The binaryformatter ... I never got that one to work properly with L2S entity objects having relationships to other entities. Long time since I tried though, so maybe I just did something wrong...
Another point to add to the accepted answer:
Relationships that are not collections will never be serialized by DataContractSerializer (whether they are loaded or not), because no DataMember attribute is generated for them from the .dbml file.
I found here an explanation by then-at-Microsoft Daniel Simmons:
The issue here is that prior to SP1 there was really no good way with DataContract serialization to handle graphs of objects that had cycles. As a result for LINQ to SQL the compromise decision was made to allow users to opt-in for uni-directional serialization and to only serialize collections not references. This mechanism doesn't work well for cases where you really want to serialize a reference (like your scenario above), but it at least gets you going for some common scenarios.
In SP1 new support was added to WCF which enables DataContract serialization to deal with cycles, but it is something you must opt-in to by changing some of your DataContract attributes and potentially also making changes to your collection and reference class implementations to properly handle the serializaiton and especially the deserialization behaviors of WCF. In the Entity Framework the changes were made to take advantage of these new features since it had not yet released its very first version, but Linq to SQL only had a small service-pack upgrade in sp1 and it was not modified to take advantage of this capability.
I have not experimented with this on L2S, but it might be possible to generate your own classes which work with L2S and have the right support for WCF serialization with cycles.
Danny

Data Repository - business objects?

I'm reading the book "ASP.NET 3.5 Social Networking - Andrew Siemer" and I got confused when he uses Repositories to access the data.
Here is the idea of his code:
public interface IAccountRepository
{
Account GetAcountByID(int acId);
void SaveAccount(Account account);
List<Account> GetAllAccounts();
}
public class AccountRepositoryLINQ : IAccountRepository
{
Account GetAcountByID(int acId){
..... LINQ query .....
...... return.....
}
void SaveAccount(Account account){
..... LINQ .....
}
List<Account> GetAllAccounts(){
..... LINQ query .....
...... return.....
}
}
The class "Account" is the one generated automatically on the "LINQ to SQL Classes".
Some of the problems I see:
1º
I code my business layer, GUI, etc... and later in time the table Accounts in the database is changed (example: change the name of one column), then I need to rebuild the "LINQ to SQL Classes" and all my code layers will need to be recoded because my "Account" object changed.
2º
If I need to have other repositories (MySQL, Oracle, XML, other), what "Account" class will I use?
What to do?
Shouldn't I use a custom Account class? This will be used in all application layers.
How do the mapping from LINQ to my custom Account class?
Using simple "myClass.Name = linqClass.Name;" ???
Isn't this consuming machine resources if I need to "map" all the classes?
There isn't a easiest/lightest way to do it?
Is this the correct approach? Is there other ways?
Good instinct..
My suggestion is to abstract away the LinqToSQL objects, and create a set of Business Domain Objects. Then the Repository can query for the needed data and map them to the Domain objects that your application uses, and return those. Now your Data Access layer is decoupled from your application, and you can now do all of the things you listed.
The mapping can be a pain, so look at tools like Automapper to accomplish this.
I have a love hate relationship with LINQ to SQL classes myself, but I thought I'd play devils advocate :-), firstly addressing the points you made:-
1º I code my business layer, GUI,
etc... and later in time the table
Accounts in the database is changed
(example: change the name of one
column), then I need to rebuild the
"LINQ to SQL Classes" and all my code
layers will need to be recoded because
my "Account" object changed.
The general approach is that you'd add behaviour to the partial classes generated by LINQ to SQL, these files won't be replaced when you refresh a table from the data context. If you change the name of the column and don't want to change the rest of your code just update the class in the designer to use the old column name?
Even if you used POCOs for persistence with NHibernate for instance you'd still need to change the mapping so I don't really see this as an issue.
2º If I need to have other repositories (MySQL, Oracle, XML, other),
what "Account" class will I use?
Personally I'd call YAGNI on this one, if you really anticipate needing support for multiple databases LINQ to SQL might not be the best solution to start with in any case (simply to keep your infrastructure consistent across the application), tools like NHibernate would have far better support for such situations.
Moving on to adding a custom account class, mapping code can be taken care of by tools like AutoMapper, though this might mean you give up things like lazy loading (which may or may not be a big deal to you).
In the end it can be quite empowering to have full control over your entities (e.g. not having to use a parameterless constructor, control over instatiation etc, simple user types that map to one or two columns) and if you feel that your application might benefit from this it's probably the way to go, but you will pay the price in the repository implementation which will be complicated by mapping code and handling whether things need to be updated / deleted / inserted.
A good middle ground might be to simply code to an interface (e.g. IAccount) this should define the properties and method you expect from an account. Your repository would then become
IAccount GetById(int accountId);
You'll then give yourself freedom over what the implementation is (i.e. whether it's implemented by a LINQ to SQL class or a projection / mapping) and if you do opt for a custom class in future it'd be a simple case of moving the implementation to that class and altering the repository implementation.
In the end it's down to the application, if you think it's going to end up a huge application with extremely complex business logic by all means I would opt for a segregated domain layer that at least tries to be persistence ignorant. If, however, it isn't and opting for the repository pattern is simply a means to achieve good testability and a simple abstraction above your data access. I don't see why explicitly referencing LINQ to SQL classes and using them as a simple domain layer is such a big deal.
I personally use a combination of NHibernate and FluentNHibernate and seperate my domain(business objects) from all other things. I use messages from my other layers, like a GUI, to my domain which has a handler which injects repositories inside that hydrate the object(s) in question and perform the business logic, the interfaces in the repositories above are a nice way to decouple if you want to use other implementations of repositories or data access.

Does Model Driven Architecture play nice with LINQ-to-SQL or Entity Framework?

My newly created system was created using the Model Driven Architecture approach so all I have is the model (let's say comprehensive 'Order' and 'Product' classes). These are fully tested classes that support the business of my application. Now it's time to persist these classes as objects on the harddrive and at some later time retrieve them in the same state (thinking very abstractly here). Typically I'd create an IOrderRepository interface and eventually a ADO.NET-driven OrderRepository class with methods such as GetAll(), GetById(), Save(), etc... or at some point a BinaryFormatter-driven OrderRepostiroy class that serves a similar purpose through this same common interface.
Is this approach just not conducive to LINQ-To-Sql or the Entity Framework. Something that attempts to build my model from a pre-existing DB structure just seems wrong. Could I take advantage of these technologies but retain this 'MDA' approach to software engineering?
... notice I did not mention that this was a Web App. It may or may not be -- and shouldn't matter.
In general, I think that you should not make types implementing business methods and types used for O/R mapping the same type. I think this violates the single responsibility principle. The point of your entity types is to bridge the gap between relational space and object space. The point of your business types is to have collections of testable behavior. Instead, I would suggest that you project from your entity types onto your business types when materializing objects from the database. Separating these two allows your business methods and data mappings to evolve independently, which is very important, especially if you cannot always control the schema of the database. I explain this idea more fully in this presentation.

Pattern name for projecting DAL specific classes (such as LINQ to SQL classes) to POCO's

I was studying the Oxite project on Codeplex. It has repository interfaces, and an implementation using LINQ to SQL. The LINQ to SQL results are projected to POCO objects in the repository implementations. It looks something like:
public IQueryable<Post> GetPosts()
{
return projectPosts(excludeNotYetPublished(getPostsQuery(siteID)));
}
This is an interesting pattern, so I wondered if it has a specific name.
Thanks!
Data Mapper. See it mentioned here http://www.martinfowler.com/eaaCatalog/repository.html
"In such systems it can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated".
Note that there are different views on this. I would say those that subscribe to doing that, claim the linq2sql classes are specific to the data access technology, so I guess they see it as an implementation detail of the repository.
Perhaps you mean to ask for a name on the "repository" that returns an IQueryable. I don't think there is a commonly agreed name for that one. Rob Connery used this one on his asp.net mvc storefront series: http://blog.wekeroad.com/mvc-storefront. If you look at the old blog posts on it, you can see calling a repository is actually controversial.
I think this is more of the Data Transfer Object (DTO) pattern, where results are turned into a DTO for transfer across layers. See Data Transfer Object.