views:

311

answers:

6

Datareader is more efficient that datatable if you need only show some data but not manipulate it. However , to get a datareader from dataaccess layer I should left the connection object open.I think this is also very big efficiency problem. Is there any approach to this to take the full advantage of datareader?

A: 

If you want to completely abstract the connections and ceremony of ADO.NET, the DataReader is a small challenge. I really don't like my data tool having an open connection on the loose, hoping the DataReader is disposed (assuming you used option CommandBehavior.CloseConnection). Also, when using a lot of DataReaders, it's difficult to pool connections, since you can't do anything with the connection until the previous DataReader is closed. They can't be passed around easily. Your Data-tool is not a true abstraction.

DataTables on the other hand are extremely flexible and can make for some very efficient, clear code. Linq-To-DataTable is great. Luckily the DataTable is actually pretty efficient. For non-huge result-sets it is almost as fast as the datareader. (it depends of course on exactly what you're doing.) More and more I am getting DataTables from my data-tool rather than Readers. It really makes life simple. I can continue to use the same open connection. There's no "state" in data-tool.

The code for getting a DataReader is very simple. So when I really do need a DataReader (not often), I just let my DAL hand me my connection and I get my DataReader myself.

Patrick Karcher
DataTables are a lazy way of returning data and lead to unmaintainable code. You should use Readers and return objects.
Keith Rousseau
@Keith Rousseau, it looks like we're going to disagree. For instantiating one or a small amount of objects, datatables give simplicity and flexibility. Maybe you'll want your data as XML? From DataTable, no problem. The efficiency your get from DataReaders is often small and not worth it.
Patrick Karcher
I can come up with a lot of examples. With DataRows you can have fantastic flexibility in constructing your objects; you can construct a ton of objects from one db-query and a single LINQ statement. The efficiency your get from DataReaders is often small and not worth it. If by *lazy* you mean constructing many objects with a **small** amount of code that's very clear and with no possibility of junior programmers leaving connections hanging open, then yes, I am lazy. I want it done quickly, clearly, and with no problems.
Patrick Karcher
My issue with DataTables has nothing to do with efficiency. It is about code maintainability and the use of magic strings. You lose strong typing, which you get from returning objects from the Data Access Layer. This makes for code that is much harder to maintain, extend and debug.
Keith Rousseau
I don't quite understand where you're coming from. Of course you *work with* strongly typed objects in your business logic and UI. My ADO.NET work serves only to put data into objects, and it sounds like you're the same way. But at some point, either in factory method or inside your objects or wherever, you are getting data from the db. This question was about, if you use a tool to abstract out your ASP.NET work, whether to go with DataReaders or DataTables. When I'm shovelling data into my objects for higher tiers to work with, I'm finding DataTables are more often better.
Patrick Karcher
+2  A: 

Yes, the data reader is definitely the most efficient - but you do not want to keep a connection open for a long period of time!

  • use the DataReader to read your data into an entity object; open the connection, read the data, close the connection
  • do whatever you need to do with your business object
  • store the changes back, e.g. by using an ad-hoc SQL query, a stored procedure, or whatever else you want; again: open the connection, write back the changes, close the connection

This is probably the most efficient you can get - it's a bit of work, some boring code, and all, but it's about as fast as it can be.

If you're more interested in developer productivity than raw speed, why not use some kind of an ORM to do all this boring, annoying mapping back and forth? Saves you a lot of coding and messy stuff to maintain!

marc_s
Thank you for the answer. I normally use ORM or create my custom business logic layer with my entity objects. However, for a small project I tried just to use data reader. Is there anything I can do except orm or entity objects?
erasmus
@erasmus If it's truly a small project, don't worry about efficiency. Just use whatever is easiest for you. There's no rule that every application needs to perform as well as it possibly can. The only expectation is that it performs as well as it needs to in order to meet the expected needs.
Mike Mooney
@erasmus: agree with Mike - the smaller the project, the less crucial is the last bit of performance. Use Linq-to-SQL, NHibernate or something - it's just *much* easier to get things done which is definitely more important in a small project
marc_s
+1  A: 

Let your data layer return objects, not datatables or data readers. I would suggest you populate your objects using a data reader.

Robert
Is it ok for my view layer to know about my domain objects?
jim
there is no domain object here if you mean entities.
erasmus
@jim - that is a completely separate question, but the answer is typically no.
Keith Rousseau
+1 @Keith Rousseau.
erasmus
@jim - your View layer should not rely on the specific structure of the tables upon which your Data layer is built. However, if by "domain objects" you mean the business objects (or "models") then, yes, these are the lingua franca for communications between the UI and the BLL. Now, you'll find many cases where the *mapping* from data objects to models (domain objects) is pretty trivial and you'll be tempted to just skip the formalities but don't - you'll be glad you kept them separate down the road.
Mark Brittingham
@Keith, @erasmus - what is your definition of a domain object? In the AI community and software in general as far as I've read, the term "domain object" is pretty specifically the objects of the world - those with which we think, compute or display. These are *mapped* to low-level representations in a database but they are not the same thing. By your answer, you seem to be thinking of "domain object" as something akin to a database record.
Mark Brittingham
@Mark - By the time you get to your View or UI you should be mapping to ViewModels, made specifically for displaying to the UI.
Keith Rousseau
@Keith - I see what you are after. It may be the kind of projects that I work on or the fact that I am a solo developer but the abstractions that I create (the Models) are typically used in both the BLL *and* the UI. I don't typically abstract away from the database layer for the BLL and then abstract away a second time for the UI (they'd end up being too similar anyway). As I'm typing this, I can actually think of a case where I *have* done this but, certainly, it isn't the usual case for me. Thanks for your thoughts, though.
Mark Brittingham
+1  A: 

What I usually do is open the reader with CommandBehavior.CloseConnection. Then I run through the reader and read the data into my own object model or list or whatever in memory with the data and then close the reader. It does much of the same stuff as a data table, but I just hate dealing with bloated and loosely-typed data stuctures.

Mike Mooney
A: 

When I researched this before, I believe I discovered that the performance difference between DataReader and DataTable was trivial, except for perhaps very large amounts of data. Since then, I have typically used DataTable as it's more full-featured, can be worked with disconnected, etc.

alchemical
what was the results? can you give us?
erasmus
+2  A: 

I never let a DataReader out into the wild (out of the DAL). Only a matter of time before you are leaving connections open somewhere. Also, I’m almost never dealing with so much data on a single call where passing around a DataTable or DataSet presents a problem.

We are using an object oriented language and the DAL can really take advantage of this. There should only be one line of code in your project that gets the connection string. Only one object that actually touches the database (calls ExecuteNonQuery, DA.Fill(), etc.)

This also lets you get pretty involved with logging exceptions, etc. because you are only doing it once. So in the one DAL base class that I use for all of my DAL object in all of my project I have the logic that if the DAL throws an exception then it is logged to a table in my database. This logging fails-over to a text file if the database logging fails.

So the code I see a lot looks like:
-   Start a try block
-   Make a SQLCommand
-   Get connection string.
-   Make Connection object
-   Open the connection
-   Get the data
-   Bind the data
-   Close the connection
-   Log error if exception

Since I encapsulate all of this, my code to get the data now looks like:

GridView1.DataSource = cProgram.DB.getMyData();

(or more likely a BAL object sits between the 2). The DB is a normal object (not static), but it only instantiated once per application.

JBrooks