Re: Performance better with DataSet or DataReader or ...??? by Dave
Dave
Mon Nov 15 16:14:51 CST 2004
One last thing as a follow up. The performance of a data reader is better
if you're going to access the contents directly but in this case, it sounds
like there would be no performance gain by using one method or the other
since you were going to just going to do manually what the DataAdapter does
automatically through the Fill() method.
The Fill() method would probably be a better choice here since you're
essentially going to have to maintain a copy of the database structure in
your application. If you were to use a DataReader to populate a DataTable
and if you were to ever change the structure of the database (highly
probable) then you'll have to not only update the code, you'll also have to
recompile and redistribute the application.
One may argue that you'd have to do that anyway since if the data structure
changed then the application probably would too so you'd have to
recompile/redistribute anyway but I say that it not only depends on the
change. Additionally, adding the complexity of maintaining a copy of the
data structure simply introduces another place for your code to break. I'm
a strong believer in keeping code at its simplest form.
Good luck!
"gwenda" <nina@community.nospam> wrote in message
news:4FACC47B-7444-4AFB-83B7-62E8157F816C@microsoft.com...
> Hi Kevin and Dave,
> First, let me thank you for your answers which were very helpful. I
> especially liked the idea of exposing parts of the DS through my
> properties.
> Second, let me clear one issue just to make sure we understand each other.
> I
> mentioned in my previous message that my objects are filled in the data
> layer
> and then being sent to the client (through a business layer and a service
> layer). So in any case I wasn't planning to leave an open connection to
> the
> DB from the client. The connection is opened; the object is filled; and
> the
> connection is closed. Since dataReaders usually perform better than DS, I
> thought it would be better to use it - for example:
>
> public MyClass GetMyClass(int myClassID)
> {
> const string procName = "P_Get_MyClass_By_ID";
> MyClass myClass = null;
> SqlParameter[] sqlParameters = new SqlParameter[]{new
> SqlParameter("@myClass_ID", myClassID)};
> using (SqlDataReader myClassReader =
> SqlHelper.ExecuteReader(connectionString,CommandType.StoredProcedure,
> procName, sqlParameters))
> {
> while (myClassReader.Read())
> {
>
> if(myClass == null)
> {
>
> myClass = new MyClass (myClassReader.GetInt32(0),
> myClassReader.GetString(1), new DataSet("contactsList"));
> }
> }
> myClass.childrenCollection.Tables.Add("Children");
>
> myClass.childrenCollection.Tables["Children"].Columns.Add("Favorite_color",
> System.Type.GetType("System.String"));
>
> myClass.childrenCollection.Tables["Children"].Columns.Add("Speed"),
> System.Type.GetType("System.String"));
> if(myClass.NextResult())
> {
> while
> (myClassReader.Read())
> {
>
> myClass.childrenCollection.Tables["Children"].Rows.Add( new
> object[]{myClassReader.GetString(0), clientReader.GetString(1)});
> }
> }
> }
> }
>
> Following your answers, I understand this code is harder to maintain but I
> want to be sure that performance-wise its better too - taking into account
> that the connection is not kept open through the whole client session.
>
> Thank you both again,
> Gwenda
>
>
>
> "Dave Fancher" wrote:
>
>> Sorry for not getting this back yesterday. It sounds like you may still
>> have an opportunity to rework your schema a bit but without the schema I
>> can't really give you any guidance on that (and depending on your
>> progress
>> on the project it might not be an option).
>>
>> I'd like to extend on what Kevin has said below. If you populate a
>> DataSet
>> with the two result sets returned from your stored procedure you will
>> definately reduce the load on your DB Server (but, since you're using
>> MSDE,
>> I doubt it would make much difference overall). Also consider this
>> though:
>> It doesn't sound like you really need to manage the relationship with the
>> DataSet because (from my understanding of you're previous posts), you're
>> going to populate the private fields of your class with the parent's
>> information, then reference the children through the dataset.
>>
>> If this is the case, If you only have the one "Collection" you can just
>> replace the DataSet field with a DataTable field and call the copy()
>> method
>> of the DataTable in your DataSet to copy the DataTable into your class.
>> You
>> could then dispose of your data set and get rid of the overhead it
>> causes.
>> Furthermore, you stated that you were using the DataSet to "track what
>> was
>> changed in them by the user," The individual data tables are responsible
>> for managing the changes, not the DataSet.
>>
>> If you do, indeed have multiple "Collections" you should probably follow
>> Kevin's advice and use the DataSet with DataRelations but rather than
>> populate member fields in your class, just create properties that expose
>> only what needs to be exposed. For example:
>>
>> public class MyClass
>> {
>> private DataSet peopleInfo;
>>
>> public int ID
>> {
>> get { return (int)(peopleInfo.Tables["Parent"].Rows[0]["ID"]); }
>> }
>>
>> public string Name
>> {
>> get { /* code to get the name here */ }
>> set { /* code to set the name here */ }
>> }
>>
>> public DataTable Children
>> {
>> get { return peopleInfo.Tables["Children"]; }
>> }
>> }
>>
>> I hope this helps
>>
>> "Kevin Yu [MSFT]" <v-kevy@online.microsoft.com> wrote in message
>> news:NV6JseUyEHA.2916@cpmsftngxa10.phx.gbl...
>> > Hi Gwenda,
>> >
>> > First of all, I would like to confirm my understanding of your issue.
>> > From
>> > your description, I understand that you need to know the best way to
>> > fill
>> > the childrenCollection DataSet. If there is any misunderstanding,
>> > please
>> > feel free to let me know.
>> >
>> > In my opinion, I will try to fill the two tables to a single DataSet
>> > and
>> > create a DataRelation between two tables. We can use GetChildRows to
>> > get
>> > the children table rows according to the parent ID and put them to the
>> > objects. This will help to lower the workload of database server, since
>> > a
>> > DataReader will require an open connection to the database. If many
>> > clients
>> > will connection to the server simultaneously, this would be a good
>> > practice. It does all the object filling at client side.
>> >
>> > Kevin Yu
>> > =======
>> > "This posting is provided "AS IS" with no warranties, and confers no
>> > rights."
>> >
>>
>>
>>