HighTechTalks DotNet Forums  

DataReader and Master-Detail

Dotnet Framework (ADO.net) microsoft.public.dotnet.framework.adonet


Discuss DataReader and Master-Detail in the Dotnet Framework (ADO.net) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Christian Schmidt
 
Posts: n/a

Default DataReader and Master-Detail - 09-01-2006 , 10:42 AM






Hi all,
I need to work through a master and its details table. My first attempt
was to open a DataReader on the master and for each record get a new
DataReader on the detail, restricted to the foreign key. But this is
very slow. As the tables are very large I cannot use DataSet's
functionality.
So my idea was to use a stored procedure for the detail reader that
returns details in the same order as the master.
1) Can this be done with a stored procedure? How?
2) Is there a better way?

Thanks for any advice,

Christian

details.read();
while (master.Read()) {
int key = master.GetInt32(masterPrimaryKeyCol);
while (details.GetInt32(detailForeignKeyCol) == key) {
// process details
// ...
details.read();
} // while details
} // while master

Reply With Quote
  #2  
Old   
Marina Levit [MVP]
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 11:48 AM






What are you trying to actually accomplish?

If you have a lot of rows, then it will take time. This all also depends on
what sort of processing you are doing with the retrieved data.

You can sort the detail data using the same sort as the master day, so all
the details rows for master 1 will be first, followed by all detail records
for 2, and so on.

"Christian Schmidt" <none (AT) locom (DOT) de> wrote

Quote:
Hi all,
I need to work through a master and its details table. My first attempt
was to open a DataReader on the master and for each record get a new
DataReader on the detail, restricted to the foreign key. But this is very
slow. As the tables are very large I cannot use DataSet's functionality.
So my idea was to use a stored procedure for the detail reader that
returns details in the same order as the master.
1) Can this be done with a stored procedure? How?
2) Is there a better way?

Thanks for any advice,

Christian

details.read();
while (master.Read()) {
int key = master.GetInt32(masterPrimaryKeyCol);
while (details.GetInt32(detailForeignKeyCol) == key) {
// process details
// ...
details.read();
} // while details
} // while master



Reply With Quote
  #3  
Old   
William \(Bill\) Vaughn
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 12:06 PM



Rules for an efficient application:
1) Do not recreate (download) the entire database or entire tables to the
client.
2) See 1.

When working with relational databases we use the SQL engine to return
relational "products" from SELECT statements that use the JOIN operator to
build correlated sets of rows--some columns drawn from several related
tables.

While the ADO.NET DataSet/DataTable approach appears to mimic this, it only
works efficiently if you return a small subset of the rows to the DataTable.
Sure, you can use the DataReader but why? The DataAdapter Fill method can
return selected rows from several tables in a single operation if you aren't
accessing JET.
Trying to pull rows from a parent table and related rows from a child table
is precisely what SQL is designed to do. No, you don't have to do a JOIN,
you can simply write two SELECT statements: one that returns _selected_
parent rows and a second that returns children from that subset of parent
rows. Yes, this can all be encapsulated in a SP that returns multiple
resultsets. If you use the Fill method to execute it, ADO.NET will
automatically create two DataTable objects in the DataSet. You can add
relationships to those afterwards.

All of my books since the first Hitchhiker's Guide to the ADO.NET books
discuss this concept in some detail. So do many others. I suggest you do
some reading...

hth

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________

"Christian Schmidt" <none (AT) locom (DOT) de> wrote

Quote:
Hi all,
I need to work through a master and its details table. My first attempt
was to open a DataReader on the master and for each record get a new
DataReader on the detail, restricted to the foreign key. But this is very
slow. As the tables are very large I cannot use DataSet's functionality.
So my idea was to use a stored procedure for the detail reader that
returns details in the same order as the master.
1) Can this be done with a stored procedure? How?
2) Is there a better way?

Thanks for any advice,

Christian

details.read();
while (master.Read()) {
int key = master.GetInt32(masterPrimaryKeyCol);
while (details.GetInt32(detailForeignKeyCol) == key) {
// process details
// ...
details.read();
} // while details
} // while master



Reply With Quote
  #4  
Old   
Christian Schmidt
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 02:03 PM



Hi Marina,
thanks for your interest.

Quote:
What are you trying to actually accomplish?
I need to do calculations (that cannot be expressed in SQL) on master
detail structures, e.g. given a set of shipments (~1E6) with containers
(~5E6), I need to determine which of these shipments fit on which
transporter.

Quote:
If you have a lot of rows, then it will take time.
Running through the records with a DataReader takes acceptable time
(using SqlConnection to a SQL 2000 Server). What does not take
acceptable time is opening a DataReader on the details for each master
record. So that's why my idea is to run through the details in the same
order (regarding the foreign key) as the master's primary key occur.

Quote:
You can sort the detail data using the same sort as the master day, so all
the details rows for master 1 will be first, followed by all detail records
for 2, and so on.
That's exactly what I want, but: The select-statement for the master has
already an order by, so I cannot simply sort the details by the foreign
key. Any ideas?

Cheers,
Christian

Quote:
"Christian Schmidt" <none (AT) locom (DOT) de> wrote in message
news:uNPrZSdzGHA.1288 (AT) TK2MSFTNGP03 (DOT) phx.gbl...
Hi all,
I need to work through a master and its details table. My first attempt
was to open a DataReader on the master and for each record get a new
DataReader on the detail, restricted to the foreign key. But this is very
slow. As the tables are very large I cannot use DataSet's functionality.
So my idea was to use a stored procedure for the detail reader that
returns details in the same order as the master.
1) Can this be done with a stored procedure? How?
2) Is there a better way?

Thanks for any advice,

Christian

details.read();
while (master.Read()) {
int key = master.GetInt32(masterPrimaryKeyCol);
while (details.GetInt32(detailForeignKeyCol) == key) {
// process details
// ...
details.read();
} // while details
} // while master



Reply With Quote
  #5  
Old   
Marina Levit [MVP]
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 02:11 PM



I guess it all depends on your query for the detail data. You must be
joining on the primary key of the master - so why not sort on that for both
result sets.

Opening a datareader isn't what isn't acceptable. It is the time to run the
query - that is what opening a datareader is. So if your query takes too
long, then perhaps you need to optimize it so it runs faster, or make sure
you have the right indexes on your tables, etc.

"Christian Schmidt" <none (AT) locom (DOT) de> wrote

Quote:
Hi Marina,
thanks for your interest.

What are you trying to actually accomplish?

I need to do calculations (that cannot be expressed in SQL) on master
detail structures, e.g. given a set of shipments (~1E6) with containers
(~5E6), I need to determine which of these shipments fit on which
transporter.

If you have a lot of rows, then it will take time.

Running through the records with a DataReader takes acceptable time (using
SqlConnection to a SQL 2000 Server). What does not take acceptable time is
opening a DataReader on the details for each master record. So that's why
my idea is to run through the details in the same order (regarding the
foreign key) as the master's primary key occur.

You can sort the detail data using the same sort as the master day, so
all the details rows for master 1 will be first, followed by all detail
records for 2, and so on.

That's exactly what I want, but: The select-statement for the master has
already an order by, so I cannot simply sort the details by the foreign
key. Any ideas?

Cheers,
Christian

"Christian Schmidt" <none (AT) locom (DOT) de> wrote in message
news:uNPrZSdzGHA.1288 (AT) TK2MSFTNGP03 (DOT) phx.gbl...
Hi all,
I need to work through a master and its details table. My first attempt
was to open a DataReader on the master and for each record get a new
DataReader on the detail, restricted to the foreign key. But this is
very slow. As the tables are very large I cannot use DataSet's
functionality.
So my idea was to use a stored procedure for the detail reader that
returns details in the same order as the master.
1) Can this be done with a stored procedure? How?
2) Is there a better way?

Thanks for any advice,

Christian

details.read();
while (master.Read()) {
int key = master.GetInt32(masterPrimaryKeyCol);
while (details.GetInt32(detailForeignKeyCol) == key) {
// process details
// ...
details.read();
} // while details
} // while master



Reply With Quote
  #6  
Old   
Christian Schmidt
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 02:47 PM



Hi Marina,
Quote:
I guess it all depends on your query for the detail data. You must be
joining on the primary key of the master - so why not sort on that for both
result sets.
Because I need to run through the master in a special order (shipments
ordered by address, ...)
But indeed for the details, I could "select details.* from details inner
join master ... order by <masters order by>". Good point!

Quote:
Opening a datareader isn't what isn't acceptable. It is the time to run the
query - that is what opening a datareader is. So if your query takes too
long, then perhaps you need to optimize it so it runs faster, or make sure
you have the right indexes on your tables, etc.
That's what I guessed first, too, but I have a clustered index on the
foreign keys in the detail table.

Thanks for your help.


Reply With Quote
  #7  
Old   
Christian Schmidt
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 03:15 PM



Hi William,
Quote:
Rules for an efficient application:
1) Do not recreate (download) the entire database or entire tables to the
client.
2) See 1.
I knew that someone would say this, but I dont't see an other option:
I need to find shipments (=master) consisting of containers (=details)
that fit on a transport. As I need to run through all shipments anyway,
don't see an other way than using a DataReader.

Quote:
When working with relational databases we use the SQL engine to return
relational "products" from SELECT statements that use the JOIN operator to
build correlated sets of rows--some columns drawn from several related
tables.
I could join the master and details, but this is more data in this flat
table than in two hierarchical tables. The only thing is I need to get
the details in the right order. Marina gave me a good hint to solve the
problem, I think.

Quote:
While the ADO.NET DataSet/DataTable approach appears to mimic this, it only
works efficiently if you return a small subset of the rows to the DataTable.
Sure, you can use the DataReader but why? The DataAdapter Fill method can
return selected rows from several tables in a single operation if you aren't
accessing JET.
So you mean I should use DataAdapter to select 1000 masters, and let it
automatically select the corresponding details. But finally, the
DataAdapter uses a DataReader with "Select * From details Where
details.fk in (...)" to get it's records, sorts them by the fk and
builds a hashtable to relate them to the master records, right?
Therefore I don't see an advantage for using a DataTable over direct
usage of DataReader - assuming the details come in the right order.

Thanks.


Reply With Quote
  #8  
Old   
William \(Bill\) Vaughn
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 05:19 PM



If the calculations are too hard for TSQL, write a CLR executable (in any
CLR language including VB.NET) to handle the computations and do them
in-situ on the server. Your performance should soar. This is what CLR
functions and sps are for.

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________

"Christian Schmidt" <none (AT) locom (DOT) de> wrote

Quote:
Hi Marina,
thanks for your interest.

What are you trying to actually accomplish?

I need to do calculations (that cannot be expressed in SQL) on master
detail structures, e.g. given a set of shipments (~1E6) with containers
(~5E6), I need to determine which of these shipments fit on which
transporter.

If you have a lot of rows, then it will take time.

Running through the records with a DataReader takes acceptable time (using
SqlConnection to a SQL 2000 Server). What does not take acceptable time is
opening a DataReader on the details for each master record. So that's why
my idea is to run through the details in the same order (regarding the
foreign key) as the master's primary key occur.

You can sort the detail data using the same sort as the master day, so
all the details rows for master 1 will be first, followed by all detail
records for 2, and so on.

That's exactly what I want, but: The select-statement for the master has
already an order by, so I cannot simply sort the details by the foreign
key. Any ideas?

Cheers,
Christian

"Christian Schmidt" <none (AT) locom (DOT) de> wrote in message
news:uNPrZSdzGHA.1288 (AT) TK2MSFTNGP03 (DOT) phx.gbl...
Hi all,
I need to work through a master and its details table. My first attempt
was to open a DataReader on the master and for each record get a new
DataReader on the detail, restricted to the foreign key. But this is
very slow. As the tables are very large I cannot use DataSet's
functionality.
So my idea was to use a stored procedure for the detail reader that
returns details in the same order as the master.
1) Can this be done with a stored procedure? How?
2) Is there a better way?

Thanks for any advice,

Christian

details.read();
while (master.Read()) {
int key = master.GetInt32(masterPrimaryKeyCol);
while (details.GetInt32(detailForeignKeyCol) == key) {
// process details
// ...
details.read();
} // while details
} // while master



Reply With Quote
  #9  
Old   
Christian Schmidt
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-01-2006 , 05:48 PM



Hi William,
Quote:
If the calculations are too hard for TSQL, write a CLR executable (in any
CLR language including VB.NET) to handle the computations and do them
in-situ on the server. Your performance should soar. This is what CLR
functions and sps are for.
Can these CLR executables be uploaded during runtime? Do you have some
good weblinks on this stuff?
Will it work for the express/MSDE editions, too?

So for data-intensive calculations you would advise against multi-tier?

Thank you very much fo your patience :-)


Reply With Quote
  #10  
Old   
William \(Bill\) Vaughn
 
Posts: n/a

Default Re: DataReader and Master-Detail - 09-02-2006 , 12:30 PM



As I describe in Chapter 13 of my new book (due out in early November) CLR
executables become part of the database--like a TSQL stored procedure. They
are supported in any SQL Server 2005 SKU--including SQL Server Express
Edition.
I cannot endorse applications that use the client as a replacement for code
that should be executed on the server. If the only purpose of the
application is to perform bulk calculations, then that work needs to be done
on the data where it resides. It's far too expensive to transport the data
to the client, change it and put it back. It unnecessarily increases network
traffic for both trips, locks on the server, load on the client and client
dissatisfaction with your approach.

hth

--
____________________________________
William (Bill) Vaughn
Author, Mentor, Consultant
Microsoft MVP
INETA Speaker
www.betav.com/blog/billva
www.betav.com
Please reply only to the newsgroup so that others can benefit.
This posting is provided "AS IS" with no warranties, and confers no rights.
__________________________________

"Christian Schmidt" <none (AT) locom (DOT) de> wrote

Quote:
Hi William,
If the calculations are too hard for TSQL, write a CLR executable (in any
CLR language including VB.NET) to handle the computations and do them
in-situ on the server. Your performance should soar. This is what CLR
functions and sps are for.

Can these CLR executables be uploaded during runtime? Do you have some
good weblinks on this stuff?
Will it work for the express/MSDE editions, too?

So for data-intensive calculations you would advise against multi-tier?

Thank you very much fo your patience :-)



Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.