I'm returning DataTable in DAL. And I have a businessObject called Customer. Where should I fill this object? Should it be done in DAL? Or in my front-end app? or where? A little cofused.
If at all possible, you want to avoid returning DataTable in your DAL and instead return the properly filled business object. There are several tools that will help you with this, for example LINQ to SQL, Entity Framework, or (my current favorite) Dapper.NET (used by this very site). I like Dapper best because it's lightweight and works well with a Data Repository pattern, which I frequently use.
You could have a Base DAL, which returns DataTables. Then have an Upper DAL, which does the converting to and from entities, (this is what I tend to use)
You really shouldn't be referring to DataTables in your UI layer.
A half-way house that I have seen before is doing the 'object filling' within a method in the actual business object itself, but that doesn't allow you to switch out your DAL so easily.
When crossing domains like this, where the representation of the data is different in each, you need an integration layer that will take care of the mapping between both representations. Most ORM tools do that mapping for you automatically, though.
But to stick with your example, you could have a layer of mappers to do that. CustomerMapper would then map from the DataTable to the Customer, effectively bridging the two domain representations.
It should be done in BL or Business Logic layer.
Related
I'm working on an ASP.NET MVC project in C# with an N-tier architecture.
A class (EmployeeRepo) in the database project has many functions.
Each function's natural result from the transaction is a dataset, but they are converted as per the need.
The return types are:
Dataset (with one or more tables)
DataTable
int
bool
Object (single employee)
List<Object> (list of employees)
Which is better among the two or is there a standard to follow:
Return the result as is without any conversion. The conversion should only happen at other layer and not in the database layer.
It is okay to convert the result in this layer before returning.
Return the result as is without any conversion. The conversion should only happen at other layer and not in > the database layer.
In my view, repository layer should only do one thing. And this thing is to query database without applying any business logic and return result. Why? There are some reasones such as:
it complies with Single Responsibility Principle of SOLID principles.
code becomes simpler
code becomes more reusable
class will have lesser size
easier to write tests
So all conversions are made in service layer.
In addition, it is not good idea to return Dataset (with one or more tables) or DataTable from repository. It is better to return IEnumerable<T>. I mean you should avoid to return IQueryable or DataTable from repository to avoid querying at service layer. There are many opinions about this. So you can choose what is better for you. Should Repositories return IQueryable? imho, repository should not return IQueryable as all query logic should be placed in one place and not scattered across services.
More over, I hihly recommend you to read this post about is it better to return the most specific or most general type from an action method?
Generally speaking, your repository layer will return entities and it is your service layer that will repackage those into a form appropriate for your application to consume.
Note that what constitutes an entity may differ from project to project. For instance, if you use Entity Framework then it uses ADO.NET under the hood but it packages the data into entity classes and returns those objects. You could, in theory, do the same but, if you do, I'd question why you're not already using EF or some other ORM. If you're going to use ADO.NET directly then you probably ought to be returning DataTables and/or DataSets to your service layer. You should certainly not do some of one and some of the other. Go all in with one or the other.
Part of the idea behind a separate repository layer is that multiple different service layers should be able to be laid on top and work seamlessly, so the repository layer should be pretty general, based on the data rather than the application. Conversions are going to require business logic and that belongs in the service layer.
I was debating whether to post this as an answer or vote the question as too opinion-based but I think that the roles of the various layers are well-enough accepted that it's not really opinion any more.
Ideally your repository layer returns data mapped to Domain entitites/Domain types.
So the repository implementation would convert from low level db/ado specific types to your DTOs / Domain Types.
This way, you keep your domain clean and don't let those db specific types trickle into your business domain.
What is the best practice to return data objects from Data Access Layers to Interface?
Currently, I have a layer that communicates with database and returns DataTable to business Layer and then Business Layer instatiates the Business Objects and returns to the interface. Isn't that pathetic or poor practise?
My questions are:
-What is the best way to return Data Objects from DAL?
-If the DAL shouldn't return Data Objects, then how do I get the data to interface for DataBinding?
This is not a problem but a best practice issue.
Thanks everyone in advance
Have you looked at the Repository Pattern?
http://msdn.microsoft.com/en-us/library/ff649690.aspx
http://martinfowler.com/eaaCatalog/repository.html
I'm not sure that the DAL shouldn't return Data Objects - there are many personal preferences and it depends on factors such as the scale of the application. In the majority of the (smallish) applications I build, I used a datareader in the DAL rather than filling and passing around DataTables. The DAL uses the datareader to populate business objects that are then returned as a collection to the service layer.
In a more complicated scenario where tables don't always equate to business objects, I've used the datareader to populate DTOs (Data Transfer Objects - very simply classes that just contain variables representing the table structure and no logic) that are returned as a collection to the service layer. The Service Layer constructs the business objects from one or more types of DTO.
I'm not saying this is a definitive answer though (The problem with 'best practice' questions!) but hopefully my experience can give an insight (In what to do or what not to do is debatable!). I am interested myself to see what answers others can contribute to this. I suppose one answer you'll likely get is to investigate the use of an ORM!
Solution setup:
DAL (class library)
BLL (class library)
Common (class library (some common functionality - enums, logging, exceptions,...))
Application1 (Windows Application)
Application2 (Windows Application)
WebApp (Web application)
...
Let's say I have a Customer entity, which is:
a table in SQL server
a CustomerDataTable in DAL
a Customer class in BLL
a BLL.Customer class in all the applications
What kind of objects should BLL and DAL use for communication - DataTable or List<Customer> (for example)? In first case, BLL logic should transform Customer object to DataTable and send it to DAL. In secod case, DAL layer should be aware of Customer class, which is in BLL layer. But originaly DLL references DAL and not opposite...
Should I put all classes into seperate assembly, which is referenced by all others (Common, BusinessObjects, ...)? In this case I could use Customer class in all my projects.
Should I even bother to seperate DAL and BLL when I know, that only one BLL will use my DAL. In this case I could merge them together into one project.
PS - I am reading about DataTables and a lot of people say that we shouldn't use them at all. What are better options? Maybe it is time for me to learn some ORM mapping tools :)
In my opinion you should have another Layer (seperate dll). Like "domain", where would you keep all entities like Customer.
Then simply include in all higher levels(DAL, BLL, UI and others) in hierarchy this assembly.
Sample architecture can look like this:
(Database) <-> DAL <-> BL <-> UI
and on all levels you will have access to "domain" layer.
DAL should return List not a DataTable. On some stage your development process you may want to use in DAL some OMR like NHibernate with would also return a List, probably.
it's hard to answer this general question without knowing the application domain well enough.
I would start with thinking about where future changes are most likely and try to figure out from that where flexibility is required.
my following thought are just a suggestion. feel free to consider them and change/ignore what you feel is irrelevant.
separating the DAL from the BLL is almost always a good idea. the data scheme is one thing that should be encapsulated and hidden from the rest of the application, so leave your DataTables, DataSets, ORMs or any other solution hidden in the DAL. the BLL (and layers above it) should use simple data types (meaning simple classes). I think it would be a good idea to put those classes in a Model class library that has no references and can be used everywhere.
it feels like you have a bit too much layering...do you really need a Customer class in the BLL and another one in the Application layer? could be, but I would make sure and think it twice over.
from my experience in one of my recent project (a weather web site with 200K unique visitors daily), we used link2sql for data access (mostly read only data), and simple data classes all over our ASP.Net MVC application (of course as part of models/view models). it worked quite smoothly, and we could easily change the data scheme without breaking down other layers.
as for your last question about DataTables, these objects, should you decide to use them (I would vote against), belong solely in your DAL. they should not be exposed to other layers as that would create coupling to that specific class. what if tomorrow MS invents a much better class? would you switch over now that you have a gazillion references all over your projects to the DataTables, its method and properties? would be nicer to just change your DAL to work with the NewAwsomeDataTable class and the rest of your app is blissfully ignorant.
hope that helped :)
I would use the following pattern as it allows you to upgrade to a different persistence strategy later.
UI/Consumer <--- (view models) --> BLL <--- Models ----> DAL/Persistence
Here the View models are consumed outside the BLL and models are communicated across the BLL/DAL layers.
In your case the model can be anything the DAL uses - DataTables for example or later perhaps ORM entities. The BLL is responsible to mapping between the model and view model.
As to keeping types in their own assemblies - yes for view models and in order to maintain a consistency, yes for the models as well.
Keeping the models and view models separate stops leakage of the persistence strategies outside of the BLL and thus permits future design changes to the persistence.
One advantage of this separation is that that different view model consumers can have differing view models for the same persistence model/entity. Some could be small and have few attributes and others large and rich in functionality. It also permits you to introduce offline/disconnectedness capability as the view models could be returned at differing times allowing you decide data merging strategies. This also allows you're persistence entities (e.g. tables to grow and change shape). Since this looks like a .net implementation things like AutoMapper will provide a lot of functionality out of the box
Of course this may be way overkill for your app - however I'd still maintain a BLL mapping that only talks view models to all BLL consumers. This should give you enough decoupling.
Pushing the domain entities into the dal is an option that would remove the crcular dependency, but may not match your intent. This isn't unheard of, though; for example LINQ-to-SQL gnerated entities would live in the DAL.
Other options:
put them into a common lower assembly (but that may leave your BL rather empty)
use IOC to remove / reverse the reference between BL/DAL
There are no single right answers here.
Re DataTable; personally I agree - I'm not a fan ;) However, they can be used successfully and reasonably. But if I had to use them, I'd be keeping them in the DAL as an implementation detail - and not exposing them above that.
I'm working on a small application from scratch and using it to try to teach myself architecture and design concepts. It's a .NET 3.5, WPF application, and I'm using Sql Compact Edition as my data store.
I'm working on the business logic layer, and have just now begun to write the DAL. I'm just using SqlCeComamnds to send over simple queries and SqlCeResultSet to get at the results. I'm starting to design my Insert and Update methods, and here's the issue - I don't know the best way to get the necessary data from the BLL into the DAL. Do I pass in a generic collection? Do I have a massive parameter list with all the data for the database? Do I simply pass in the actual business object (thus tying my DAL to the conrete stuff in the BLL?).
I thought about using interfaces - simply passing IBusinessObjectA into the DAL, which provides the simplicity I'm looking for without tying me TOO tightly to current implementations. What do you guys think?
I don't think there is a simple answer to your questions because there are many options depending on the circumstances. I have found it helpful to read the two books below to help me understand the problems you describe better.
MS .NET: Architecting Applications for the Enterprise (Esposito, Saltarello)
MS Application Architecture Guide, 2nd edition.
The second book is available online. Look here.
I think it is OK to pass the Business object to the Data Access Layer. I think the BLL's job is just to work with its objects, to check if all rules are being followed, about what can be saved, by whom, on what fields, time, etc.
Once it has done that it should pass it to the DAL, and I think it is IT'S job to figure out how to convert what it got into something that can be persisted, but it wont check what is being persisted or read or by whom, it will just do it. This could be straight foward, a la linq, but if your logic mdoels do not match your data model 1:1, then the DAL should do all the conversion.
About tying your DAL to the stuff in the BLL, I think you should worry about the other way around, tying your BLL to your DAL. I would use an interface to represent your DAL (as in IRepository) that way you can make your BLL call any kind of persistance mechanism just by changing the type of IRepository it is using (extra points if you use IoC :P). The concrete classes that implement the IRepository would be tied to the business objects, but they have to know what is it that they are saving don't they? while the BLL does NOT have to know what is doing the saving.
To pass business object in the DAL is the simpler and fastest method. It works in small projects, but have same disadvantages:
1) Business Objects are part of BLL layer, and if you pass objects in BLL then DAL becomes dependent of BLL. low layer knows about upper one - this contradicts the idea of layers at all.
2) Business Object are usially very complex to save it directly in BD. In this case it is better to introduce new "Mappers" intermediate layer.
To overcome all these issues I usially make interface to DAL independent of Business Objects. I use "Row" classes instead - representation of one record in the database or XML. In .NET 3.5 linqtosql autogenerated classes can be used for this purpose.
If I was in your position, I'd probably use LINQ to SQL to define my data access layer - it'll save you lots of work maintaining all that SqlCeFooBar stuff and give you a designer (of sorts) for maintaining your database that you would otherwise lack, using SQL CE.
So in that case, I'd probably couple the business logic layer pretty tightly to the entities exposed by the L2S layer. The justification being that the entities are the business objects, albeit devoid of any services.
I probably wouldn't let the entities get as far up the hierarchy as the UI though. At that level, it makes much more sense to use a model specifically for the view - especially given that you're using WPF.
Of course, all of this depends upon the size and complexity of your application. I'm assuming it's a fairly small scale application (single user?) given that you're using SQL CE.
I'v e built a basic DAL which can retrieve data and a businesslayer with several objects using this DAL. Once I mapped the data into the business objects and done something with it, I also want to write the data back to the database. Some of the business objects have a lot of properties, so passing every value of a business object as parameter to a method of the corresponding dataservice is not a possibility.
Other ways I've been thinking of:
pass the business object to the the corresponding data service, there execute a SP with all the values as parameters. - sucks, because I have to pass a business object to the DAL (violating the separation) and probably end up with SPs with >50 parameters
create an empty (?) dataset within the business object, fill it with the values from the business object, pass that dataset to the data service and update the db via a dataadapter. I thought of creating an empty dataset with a "... WHERE 0"-SQL String. Would that be a good practice?
This is the first time I do something like this. The latter sounds better to me, but maybe there are other, better approaches? Or The first one is better for some reasons I don't know?
Thank you very much!
[edit:] I can't use LinQ2SQL, cuz I use C# Express (which only supports querying local DBs, while mine is a remote one)
Pass your object into your DAL. If your writting the DAL layer manually your DAL layer should know how to take an Entity and persist it to the DB, and how to return an Entity from the database. The DAL is about persistance of your entities to a non-volatile medium.
You haven't mentioned using LINQ. Is that because you're not using .NET 3.5 yet?
Also, you don't have to make your DAL that generic. The callers of your DAL aren't trying to update all properties of the business object, are they? They probably want to update parts of it, so you should present an API that does this. For instance, they might just want to add an address to a Contact object, or possibly even update a phone number. You need to have a tradeoff between doing what the caller is really trying to do, and the number of separate methods you'd need in order to do that.
The DAL should be all about mapping between your business objects and the specific data representation. This is why the Repository pattern that works with the domain objects, allows you to switch to a different persistance implementation, that might not even be a database.
You are concerned about needing to pass too many parameters to the DAL's methods, and then mention an example where you only need to pass 2 or 3 values. If that is the case, passing it as the method's arguments is reasonable. If you are passing more values, one way you can achieve it is by defining an interface with the subset of values you want to save. This way you are specifying clearly the info that method will be handling.
Regardless of the above, don't make the methods too specific, as you would end up with lots of combinations which can make it harder to mantain.
why do you think that when passing a business object to the DAL you are violating the separation. maybe you should think on separating the bussines objects into another layer.
also you could try linq2SQL in that way you can forget about parameters and this will reduce the number of your SP's.
Unless your Data Access Layer is very generic, how would passing a business object be bad?
I'm a fan of serializing the object and passing the XML to a stored proc, but I'll probably be in the minority.