Is this good object design?
Messages   Related Types
This message was discovered on ASPFriends.com 'aspngarchitecture' list.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.

James Yang
Currently, I usually make 2 objects for 1 entity..

1st object is the object that represents a single entity so in case of a
prog with users, there is a object called USER and contains methods like
Update and properties of user information and 2nd object is called USERS
which is the collection of USER objects that implement IEnumerator and
IEnumerable. and it also contains methods like Create() and delete(). and it
also has methods that retrives records fromt he data base and fill up the
collection using data reader... I have several of these methods and they
have different fns like sorting filtering within the collection...

I would use the obejcts like this

Users users = new Users()
users.GetAllUsers()
foreach (User user in users)
{
Response.Write(user.FName);
}

i could also do

users.GetUsersWithFirstName("John")

I actually do 1 database query per Get___ methods..

the question is..is this a common object design ? or am i completely lost
???

Please help me out !!!

James

PS If any one knows a good site with guide to the object design..please let
me know...

Reply to this message...
 
    
Deyan Petrov
Hi James,

For some time I have been designing a system which should use the same
approach.

I have an interface IPersistable with 2 methods - Retrieve and Update, so my
custom collections implement it.
Also my custom business collections derive from CollectionBase usually.
Also my entity classes are usually used as proxies only, with the ID set. If
other properties are needed then Retrieve is called.
I have an ObjectState enum, which consists of Unchanged, Inserted, Modified,
Deleted values. Each business entity has an ObjectState property. When I
call Update on a collection, it serializes all the entities, which are not
unchanged to XML and sends this XML to a stored procedure in the SQL Server,
which uses OpenXML and executes the approprate INSERT/UPDATE/DELETE
statements.

I have other interfaces, which allow me to treat all business entities
uniformly ...

It will be a good discussion if we hear other opinions on this design.

Regards,
Deyan Petrov

P.S. The most important in my design is that an entity/collection is usually
a hollow proxy, consisting only of IDs. If other properties are required,
then a trip to the DB is made.

----- Original Message -----
From: "James Yang" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Tuesday, June 18, 2002 12:46 PM
Subject: [aspngarchitecture] Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Jon Ceanfaglione
Doesn't "serializing all the entities" incur a large performance hit?

Jon

-----Original Message-----
From: Deyan Petrov [mailto:Click here to reveal e-mail address]
Sent: Tuesday, June 18, 2002 8:18 AM
To: aspngarchitecture
Subject: [aspngarchitecture] Re: Is this good object design???

Hi James,

For some time I have been designing a system which should use the same
approach.

I have an interface IPersistable with 2 methods - Retrieve and Update, so my
custom collections implement it.
Also my custom business collections derive from CollectionBase usually.
Also my entity classes are usually used as proxies only, with the ID set. If
other properties are needed then Retrieve is called.
I have an ObjectState enum, which consists of Unchanged, Inserted, Modified,
Deleted values. Each business entity has an ObjectState property. When I
call Update on a collection, it serializes all the entities, which are not
unchanged to XML and sends this XML to a stored procedure in the SQL Server,
which uses OpenXML and executes the approprate INSERT/UPDATE/DELETE
statements.

I have other interfaces, which allow me to treat all business entities
uniformly ...

It will be a good discussion if we hear other opinions on this design.

Regards,
Deyan Petrov

P.S. The most important in my design is that an entity/collection is usually
a hollow proxy, consisting only of IDs. If other properties are required,
then a trip to the DB is made.

----- Original Message -----
From: "James Yang" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Tuesday, June 18, 2002 12:46 PM
Subject: [aspngarchitecture] Is this good object design???

[Original message clipped]

| [aspngarchitecture] member Click here to reveal e-mail address = YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp = JOIN/QUIT
| http://www.asplists.com/search = SEARCH Archives

__________________________________________________

The information contained in this communication is intended only for the use
of the recipient named above, and may be legally privileged, confidential
and exempt from disclosure under applicable law. If the reader of this
communication is not the intended recipient, you are hereby notified that
any dissemination, distribution, or copying of this communication, or any of
its contents, is strictly prohibited. If you have received this
communication in error, please re-send this communication to the sender and
delete the original communication and any copy of it from your computer
system. Thank you.

Reply to this message...
 
    
Deyan Petrov
Hi Jon,

Why should it? Just construction of xml ... the other way would be multiple
roundtrips to the database for each entity, which I don't think is faster
.... imagine an order with 100 order lines - this means 101 roundtrips. My
way it means 1 roundtrip, of course serializing and deserializing the
entities, but ... it's all about finding the fastest solution ... I just
don't want to use up all my available db connections in case of a high user
load.

Regards,
Deyan Petrov

----- Original Message -----
From: "Jon Ceanfaglione" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Tuesday, June 18, 2002 3:49 PM
Subject: [aspngarchitecture] Re: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
James Yang
What i actually do with the collectin is that
I retrieve IDs from the database and instantiate a new object for current
property

so

public object Current
{
get
{
return new user(userIDs[1]);
}
}

istead of actually initialising all 9999999 objects... :)

----- Original Message -----
From: "Deyan Petrov" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 1:31 AM
Subject: [aspngarchitecture] Re: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Paul D. Murphy
James this is a simplified explanation of the ECC (Engine - Collection -
Class) design pattern. It's an excellent object design for developing
middle tier business objects. A couple of things that I would point out
assist you. What it looks like you are doing is making the Engine and
the Collection into one entity. I would disagree with this union of the
responsibility in one instance class.

Your users collection should maintain the responsibility of containing a
group of users. The creational aspects of the users collection should be
moved into a separate class like UserEngine. In my designs I've started
marking the engine classes as internal and exposing them on the
collection as static methods which makes coding against the classes a
breeze.

Users allNewUsers =3D Users.GetAllNew();

Where get all new looks like this

Public class Users
{
    //    instance stuff here

public static Users GetAllNew()
{
UserEngine engine =3D new UserEngine(CONNECTION,
CACHE_OPTION_PARAM);
    return engine.GetAllNew();
}
}

Paul

[Original message clipped]

Reply to this message...
 
    
Francesco Sanfilippo
I love this discussion as it has everything to do with what I am working on
at the moment, a BLL for a major community site. Please comment on the
design I am developing.

When an anonymous user arrives I create a Visitor object that maintains the
clickpath and properties from ServerVariables. Clickpath information is
saved to a DataTable in Cache (with no expiration), and the ClickLog
DataTable is dumped to SQL every n number of entries, or minutes. Once the
Visitor signs in (if a Member), I create a Member object like this:

Member thisMember = new Member(thisVisitor);

In the Member constructor, I call one stored proc and return 12 result sets
to populate a DataSet, a property of the Member class.

The Visitor/Member objects are stored in Session so we don't have to keep
retrieving the basic user-specific information on every page. When a Member
makes an update on the site to some personal data, a Stored Proc is called
that updates the appropriate tables AND returns a new representation of the
updated data to repopulate the DataTable corresponding to the relationship
that the Member updated. DataTable examples would be: MemberFriend (like a
buddy list), MemberCategory (a list of categories that the Member has
chosen).

App-wide data that never changes, like Country and Type tables, are stored
in Cache with no expiration.

Does this design sound scalable as long as I use StateServer Session state?
Is this design effective in reducing trips to the DB, without causing
problems in other areas and in other ways?

Francesco

[Original message clipped]

_________________________________________________________________
Send and receive Hotmail on your mobile device: http://mobile.msn.com

Reply to this message...
 
    
Rolly Ferolino
<<PS If any one knows a good site with guide to the object design..please
let
me know...>>

Try www.martinfowler.com. He's got the 2nd draft of his forthcoming book,
"Patterns of Enterprise Application Architecture."

Rolly

-----Original Message-----
From: James Yang [mailto:Click here to reveal e-mail address]
Sent: Tuesday, June 18, 2002 3:46 AM
To: aspngarchitecture
Subject: [aspngarchitecture] Is this good object design???

Currently, I usually make 2 objects for 1 entity..

1st object is the object that represents a single entity so in case of a
prog with users, there is a object called USER and contains methods like
Update and properties of user information and 2nd object is called USERS
which is the collection of USER objects that implement IEnumerator and
IEnumerable. and it also contains methods like Create() and delete(). and it
also has methods that retrives records fromt he data base and fill up the
collection using data reader... I have several of these methods and they
have different fns like sorting filtering within the collection...

I would use the obejcts like this

Users users = new Users()
users.GetAllUsers()
foreach (User user in users)
{
Response.Write(user.FName);
}

i could also do

users.GetUsersWithFirstName("John")

I actually do 1 database query per Get___ methods..

the question is..is this a common object design ? or am i completely lost
???

Please help me out !!!

James

PS If any one knows a good site with guide to the object design..please let
me know...

| [aspngarchitecture] member Click here to reveal e-mail address = YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp = JOIN/QUIT
| http://www.asplists.com/search = SEARCH Archives

Reply to this message...
 
    
Deyan Petrov
Hi Paul,

I wouldn't use the ECC design pattern in .NET. I don't like another engine
class with static methods, since it perferctly fits in the same class.
The ECC design pattern was used in VB primarily, where you don't have
constructors with parameters etc and is a bit procedural oriented, in my
opinion. C# is much more rich ...

Regards,
Deyan

----- Original Message -----
From: "Paul D. Murphy" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Tuesday, June 18, 2002 8:52 PM
Subject: [aspngarchitecture] RE: Is this good object design???

James this is a simplified explanation of the ECC (Engine - Collection -
Class) design pattern. It's an excellent object design for developing
middle tier business objects. A couple of things that I would point out
assist you. What it looks like you are doing is making the Engine and
the Collection into one entity. I would disagree with this union of the
responsibility in one instance class.

Your users collection should maintain the responsibility of containing a
group of users. The creational aspects of the users collection should be
moved into a separate class like UserEngine. In my designs I've started
marking the engine classes as internal and exposing them on the
collection as static methods which makes coding against the classes a
breeze.

Users allNewUsers = Users.GetAllNew();

Where get all new looks like this

Public class Users
{
// instance stuff here

public static Users GetAllNew()
{
UserEngine engine = new UserEngine(CONNECTION,
CACHE_OPTION_PARAM);
return engine.GetAllNew();
}
}

Paul

[Original message clipped]

| [aspngarchitecture] member Click here to reveal e-mail address = YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp = JOIN/QUIT
| http://www.asplists.com/search = SEARCH Archives

Reply to this message...
 
    
Deyan Petrov
Hi Francesco,

As far as I see, you are using the data-centric approach. You store the
attributes of your objects in Data structures like DataTables etc. In fact
your business classes are nothing but a holder for a DataTable with the
properties, right? So, this is not very OO, even if you pretend to have
Visitor and Member objects.
Second, you mention the StateServer ... how reliable is this StateServer I
have been always wondering ... what if you have to shut down for a while
your production state server, in order to upgrade it or whatever? Then your
site will not be functional maybe, or you can easily swich to another
StateServer in the web farm? I am not very well acquainted with this option
for session state maintainance.
Also, do you really need so much data in the cache in every page for the
Member/Visitor?
I think that the data-centric approach, which deals with data and stores it
in DataSets/DataTables eliminates some of the benefits of OOP. How can you
use here inheritance, polymorphism? Just my opinion ...

Regards,
Deyan Petrov

----- Original Message -----
From: "Francesco Sanfilippo" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 4:31 AM
Subject: [aspngarchitecture] Re: Is this good object design???

> I love this discussion as it has everything to do with what I am working
on
[Original message clipped]

Reply to this message...
 
    
James Yang
What are the alternative patterns ?? Which patterns do you use??

----- Original Message -----
From: "Deyan Petrov" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 5:30 PM
Subject: [aspngarchitecture] RE: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Deyan Petrov
Hi James,

I use 2 classes per entity - the first one is the single entity and the
second one is a custom collection of the entity. I separate the logic so,
because a SET has different operations/attributes than a single entity. Both
classes are instantiated, usually have instance methods.
I can freely inherit, implement common interfaces and use polymorhism. To me
the classes are meaningful and the methods operate on themselves in a very
meaningfull way. I use composition a lot, so a certain business entity might
have another business entity as a property, or a set of other business
entities.
I explicitely Retrieve() and Update() the entity/entity collection from/to
the database.

User user = new User(userID);
User.Retrieve();
Console.WriteLine(user.Name);
...

Users users = new Users();
users.Retrieve();
foreach(User user in users)
{
Console.WriteLine(user.Name);
}
...

user.Roles.Retrieve();
foreach(Role role in user.Roles)
{
Console.WriteLine(role.Name);
}
...

Role role = new Role(roleID);
role.Users.Retrieve();
...

user.Name = "alalabala";

IPersistable entity = (IPersistable) user;
entity.Update(); //to db

etc. etc.

I load the collections from the DB using IDataReader. I update the DB using
sprocs. In case of a big collection, I use a NTEXT sproc parameter, in which
I xml serialize all the entity, which are modified/deleted/inserted. Each
Entity has a ObjectState property, which is a enum of Unchanged, Inserted,
Modified, Deleted. In the collection's Update() method I inspect the
property on all the objects and roundtrip to db only those, who need to be
...
I use 2-way custom DataBound ASP.NET web server controls, which deal with
collections, take into consideration the ObjectState property ....

I can write more on the subject ...

Regards,
Deyan Petrov

----- Original Message -----
From: "James Yang" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 10:10 AM
Subject: [aspngarchitecture] RE: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Matias Woloski
Hi Deyan,
I like the model you're describing. But I have some questions:

1. How do you solve the 1-to-n and n-to-n relationships? I mean, you said
you have properties inside a class which holds an instance of another class,
like Users-Role. That's ok, but what about transactions in this context? For
instance, if an Order is deleted, all its Items need to be deleted. How do
you manage to do that in a whole transaction and commit it or rollback it?

2. Do you have some sample code about how do you serialize your class in
xml?

3. The databound controls has support for classes implementing IEnumerator
and IEnumerable? I mean you can bind a Collection to a Datagrid the same way
you do it with a Dataset? Which are the things you loose when using
Collections vs. Datasets?

4. I like very much the idea of OpenXML to has multiple items
inserted/changed/deleted in only one trip. But if you have to use Oracle
instead of SQL Server, how would you solve it?

thanks,
Matias

[Original message clipped]

Reply to this message...
 
    
James Yang
But isn't connection to sql server pooled???

----- Original Message -----
From: "Deyan Petrov" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 1:31 AM
Subject: [aspngarchitecture] Re: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Deyan Petrov
Hi James,

The connections are pooled, of course, but still it's faster this way
instead of multiple roundtrips.

Regards,
Deyan Petrov

----- Original Message -----
From: "James Yang" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 12:43 PM
Subject: [aspngarchitecture] Re: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Deyan Petrov
Hi Matias,

pls see inline ....

----- Original Message -----
From: "Matias Woloski" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 2:33 PM
Subject: [aspngarchitecture] RE: Is this good object design???

[Original message clipped]

Well, there are different ways to do this. In the case of a delete or
update, there is Cascade Delete and Cascade Update referential integrity in
SQL Server... If I am going to delete an Order, it is no problem, in the
sproc I'll delete the order and the order lines ... I don't understand your
question ...
If you are asking about transactions spanning multiple methods, look at
http://www.codeproject.com/csharp/dal.asp

[Original message clipped]

I haven't written yet this code, as all I have shared with you are only
design ideas with partial implemetions still. But it's simple enough, I've
done it previously to send NTEXT to a sproc and to open it with OpenXML ...
just don't know where the code is right now ...

[Original message clipped]

You can bind a databound control to everything, which implements certain
interfaces.

[Original message clipped]

I have no experience with Oracle, but I am sure there are also XML parsing
capabilites there, maybe as an extension (like SqlXml for SQL Server).

[Original message clipped]

Reply to this message...
 
    
Russ McClelland
V2UgdXNlIGEgc2ltaWxhciBhcmNoaXRlY3R1cmUgYW5kIGRvIG5vdCB1c2UgdGhlIEVDQyBwYXR0
ZXJuIGF0IGFsbC4NClRoZSBvbmx5IGRpZmZlcmVuY2UgaXMgdGhhdCB3ZSB0cmVhdCBwZXJzaXN0
ZW5jZSBhcyBhbiBleHRlcm5hbCBzZXJ2aWNlLA0Kc28gdGhlcmUgYXJlIG5vICJyZXRyaWV2ZSIg
YW5kICJ1cGRhdGUiIHR5cGUgbWV0aG9kcyBpbiBvdXIgZG9tYWluDQpjbGFzc2VzLiAgQWxsIHBl
cnNpc3RlbmNlIGlzIGhhbmRsZWQgdGhyb3VnaCBhIHNlcnZpY2UgbGF5ZXIgd2UgY2FsbA0KYnJv
a2Vycy4gIFNvbWUgImNvbnRyb2xsaW5nIiBvYmplY3QgKEFwcGxpY2F0aW9uIGxheWVyKSBkZWNp
ZGVzIHdoZW4NCnBlcnNpc3RlbmNlIGlzIHJlcXVpcmVkIGFuZCB1c2VzIHRoZSBhcHByb3ByaWF0
ZSBicm9rZXIgdG8gc2F2ZSBhDQpidXNpbmVzcy9kb21haW4gb2JqZWN0IHRoYXQgaXQgbWF5IGJl
IG9wZXJhdGluZyBvbiBhdCB0aGUgdGltZS4NCg0KCS0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0t
IA0KCUZyb206IERleWFuIFBldHJvdiANCglTZW50OiBXZWQgNi8xOS8yMDAyIDI6NDEgQU0gDQoJ
VG86IGFzcG5nYXJjaGl0ZWN0dXJlIA0KCUNjOiANCglTdWJqZWN0OiBbYXNwbmdhcmNoaXRlY3R1
cmVdIFJlOiBJcyB0aGlzIGdvb2Qgb2JqZWN0IGRlc2lnbj8/Pw0KCQ0KCQ0KDQoJSGkgRnJhbmNl
c2NvLA0KCQ0KCUFzIGZhciBhcyBJIHNlZSwgeW91IGFyZSB1c2luZyB0aGUgZGF0YS1jZW50cmlj
IGFwcHJvYWNoLiBZb3UNCnN0b3JlIHRoZQ0KCWF0dHJpYnV0ZXMgb2YgeW91ciBvYmplY3RzIGlu
IERhdGEgc3RydWN0dXJlcyBsaWtlIERhdGFUYWJsZXMNCmV0Yy4gSW4gZmFjdA0KCXlvdXIgYnVz
aW5lc3MgY2xhc3NlcyBhcmUgbm90aGluZyBidXQgYSBob2xkZXIgZm9yIGEgRGF0YVRhYmxlDQp3
aXRoIHRoZQ0KCXByb3BlcnRpZXMsIHJpZ2h0PyBTbywgdGhpcyBpcyBub3QgdmVyeSBPTywgZXZl
biBpZiB5b3UgcHJldGVuZA0KdG8gaGF2ZQ0KCVZpc2l0b3IgYW5kIE1lbWJlciBvYmplY3RzLg0K
CVNlY29uZCwgeW91IG1lbnRpb24gdGhlIFN0YXRlU2VydmVyIC4uLiBob3cgcmVsaWFibGUgaXMg
dGhpcw0KU3RhdGVTZXJ2ZXIgSQ0KCWhhdmUgYmVlbiBhbHdheXMgd29uZGVyaW5nIC4uLiB3aGF0
IGlmIHlvdSBoYXZlIHRvIHNodXQgZG93biBmb3INCmEgd2hpbGUNCgl5b3VyIHByb2R1Y3Rpb24g
c3RhdGUgc2VydmVyLCBpbiBvcmRlciB0byB1cGdyYWRlIGl0IG9yDQp3aGF0ZXZlcj8gVGhlbiB5
b3VyDQoJc2l0ZSB3aWxsIG5vdCBiZSBmdW5jdGlvbmFsIG1heWJlLCBvciB5b3UgY2FuIGVhc2ls
eSBzd2ljaCB0bw0KYW5vdGhlcg0KCVN0YXRlU2VydmVyIGluIHRoZSB3ZWIgZmFybT8gSSBhbSBu
b3QgdmVyeSB3ZWxsIGFjcXVhaW50ZWQgd2l0aA0KdGhpcyBvcHRpb24NCglmb3Igc2Vzc2lvbiBz
dGF0ZSBtYWludGFpbmFuY2UuDQoJQWxzbywgZG8geW91IHJlYWxseSBuZWVkIHNvIG11Y2ggZGF0
YSBpbiB0aGUgY2FjaGUgaW4gZXZlcnkgcGFnZQ0KZm9yIHRoZQ0KCU1lbWJlci9WaXNpdG9yPw0K
CUkgdGhpbmsgdGhhdCB0aGUgZGF0YS1jZW50cmljIGFwcHJvYWNoLCB3aGljaCBkZWFscyB3aXRo
IGRhdGENCmFuZCBzdG9yZXMgaXQNCglpbiBEYXRhU2V0cy9EYXRhVGFibGVzIGVsaW1pbmF0ZXMg
c29tZSBvZiB0aGUgYmVuZWZpdHMgb2YgT09QLg0KSG93IGNhbiB5b3UNCgl1c2UgaGVyZSBpbmhl
cml0YW5jZSwgcG9seW1vcnBoaXNtPyBKdXN0IG15IG9waW5pb24gLi4uDQoJDQoJUmVnYXJkcywN
CglEZXlhbiBQZXRyb3YNCgkNCgktLS0tLSBPcmlnaW5hbCBNZXNzYWdlIC0tLS0tDQoJRnJvbTog
IkZyYW5jZXNjbyBTYW5maWxpcHBvIiA8cGhvdG9yZWFsbUBob3RtYWlsLmNvbT4NCglUbzogImFz
cG5nYXJjaGl0ZWN0dXJlIiA8YXNwbmdhcmNoaXRlY3R1cmVAYXNwZnJpZW5kcy5jb20+DQoJU2Vu
dDogV2VkbmVzZGF5LCBKdW5lIDE5LCAyMDAyIDQ6MzEgQU0NCglTdWJqZWN0OiBbYXNwbmdhcmNo
aXRlY3R1cmVdIFJlOiBJcyB0aGlzIGdvb2Qgb2JqZWN0IGRlc2lnbj8/Pw0KCQ0KCQ0KCT4gSSBs
b3ZlIHRoaXMgZGlzY3Vzc2lvbiBhcyBpdCBoYXMgZXZlcnl0aGluZyB0byBkbyB3aXRoIHdoYXQg
SQ0KYW0gd29ya2luZw0KCW9uDQoJPiBhdCB0aGUgbW9tZW50LCBhIEJMTCBmb3IgYSBtYWpvciBj
b21tdW5pdHkgc2l0ZS4gIFBsZWFzZQ0KY29tbWVudCBvbiB0aGUNCgk+IGRlc2lnbiBJIGFtIGRl
dmVsb3BpbmcuDQoJPg0KCT4gV2hlbiBhbiBhbm9ueW1vdXMgdXNlciBhcnJpdmVzIEkgY3JlYXRl
IGEgVmlzaXRvciBvYmplY3QgdGhhdA0KbWFpbnRhaW5zDQoJdGhlDQoJPiBjbGlja3BhdGggYW5k
IHByb3BlcnRpZXMgZnJvbSBTZXJ2ZXJWYXJpYWJsZXMuICBDbGlja3BhdGgNCmluZm9ybWF0aW9u
IGlzDQoJPiBzYXZlZCB0byBhIERhdGFUYWJsZSBpbiBDYWNoZSAod2l0aCBubyBleHBpcmF0aW9u
KSwgYW5kIHRoZQ0KQ2xpY2tMb2cNCgk+IERhdGFUYWJsZSBpcyBkdW1wZWQgdG8gU1FMIGV2ZXJ5
IG4gbnVtYmVyIG9mIGVudHJpZXMsIG9yDQptaW51dGVzLiAgT25jZQ0KCXRoZQ0KCT4gVmlzaXRv
ciBzaWducyBpbiAoaWYgYSBNZW1iZXIpLCBJIGNyZWF0ZSBhIE1lbWJlciBvYmplY3QgbGlrZQ0K
dGhpczoNCgk+DQoJPiBNZW1iZXIgdGhpc01lbWJlciA9IG5ldyBNZW1iZXIodGhpc1Zpc2l0b3Ip
Ow0KCT4NCgk+IEluIHRoZSBNZW1iZXIgY29uc3RydWN0b3IsIEkgY2FsbCBvbmUgc3RvcmVkIHBy
b2MgYW5kIHJldHVybg0KMTIgcmVzdWx0DQoJc2V0cw0KCT4gdG8gcG9wdWxhdGUgYSBEYXRhU2V0
LCBhIHByb3BlcnR5IG9mIHRoZSBNZW1iZXIgY2xhc3MuDQoJPg0KCT4gVGhlIFZpc2l0b3IvTWVt
YmVyIG9iamVjdHMgYXJlIHN0b3JlZCBpbiBTZXNzaW9uIHNvIHdlIGRvbid0DQpoYXZlIHRvIGtl
ZXANCgk+IHJldHJpZXZpbmcgdGhlIGJhc2ljIHVzZXItc3BlY2lmaWMgaW5mb3JtYXRpb24gb24g
ZXZlcnkgcGFnZS4NCldoZW4gYQ0KCU1lbWJlcg0KCT4gbWFrZXMgYW4gdXBkYXRlIG9uIHRoZSBz
aXRlIHRvIHNvbWUgcGVyc29uYWwgZGF0YSwgYSBTdG9yZWQNClByb2MgaXMgY2FsbGVkDQoJPiB0
aGF0IHVwZGF0ZXMgdGhlIGFwcHJvcHJpYXRlIHRhYmxlcyBBTkQgcmV0dXJucyBhIG5ldw0KcmVw
cmVzZW50YXRpb24gb2YNCgl0aGUNCgk+IHVwZGF0ZWQgZGF0YSB0byByZXBvcHVsYXRlIHRoZSBE
YXRhVGFibGUgY29ycmVzcG9uZGluZyB0byB0aGUNCnJlbGF0aW9uc2hpcA0KCT4gdGhhdCB0aGUg
TWVtYmVyIHVwZGF0ZWQuICBEYXRhVGFibGUgZXhhbXBsZXMgd291bGQgYmU6DQpNZW1iZXJGcmll
bmQgKGxpa2UNCglhDQoJPiBidWRkeSBsaXN0KSwgTWVtYmVyQ2F0ZWdvcnkgKGEgbGlzdCBvZiBj
YXRlZ29yaWVzIHRoYXQgdGhlDQpNZW1iZXIgaGFzDQoJPiBjaG9zZW4pLg0KCT4NCgk+IEFwcC13
aWRlIGRhdGEgdGhhdCBuZXZlciBjaGFuZ2VzLCBsaWtlIENvdW50cnkgYW5kIFR5cGUNCnRhYmxl
cywgYXJlIHN0b3JlZA0KCT4gaW4gQ2FjaGUgd2l0aCBubyBleHBpcmF0aW9uLg0KCT4NCgk+IERv
ZXMgdGhpcyBkZXNpZ24gc291bmQgc2NhbGFibGUgYXMgbG9uZyBhcyBJIHVzZSBTdGF0ZVNlcnZl
cg0KU2Vzc2lvbg0KCXN0YXRlPw0KCT4gSXMgdGhpcyBkZXNpZ24gZWZmZWN0aXZlIGluIHJlZHVj
aW5nIHRyaXBzIHRvIHRoZSBEQiwgd2l0aG91dA0KY2F1c2luZw0KCT4gcHJvYmxlbXMgaW4gb3Ro
ZXIgYXJlYXMgYW5kIGluIG90aGVyIHdheXM/DQoJPg0KCT4gRnJhbmNlc2NvDQoJPg0KCT4NCgk+
DQoJPg0KCT4NCgk+DQoJPg0KCT4gPkZyb206ICJEZXlhbiBQZXRyb3YiIDxkZXlhbnBAaG90bWFp
bC5jb20+DQoJPiA+UmVwbHktVG86ICJhc3BuZ2FyY2hpdGVjdHVyZSINCjxhc3BuZ2FyY2hpdGVj
dHVyZUBhc3BmcmllbmRzLmNvbT4NCgk+ID5UbzogImFzcG5nYXJjaGl0ZWN0dXJlIiA8YXNwbmdh
cmNoaXRlY3R1cmVAYXNwZnJpZW5kcy5jb20+DQoJPiA+U3ViamVjdDogW2FzcG5nYXJjaGl0ZWN0
dXJlXSBSZTogSXMgdGhpcyBnb29kIG9iamVjdA0KZGVzaWduPz8/DQoJPiA+RGF0ZTogVHVlLCAx
OCBKdW4gMjAwMiAxNDoxODoxNiArMDIwMA0KCT4gPg0KCT4gPkhpIEphbWVzLA0KCT4gPg0KCT4g
PkZvciBzb21lIHRpbWUgSSBoYXZlIGJlZW4gZGVzaWduaW5nIGEgc3lzdGVtIHdoaWNoIHNob3Vs
ZCB1c2UNCnRoZSBzYW1lDQoJPiA+YXBwcm9hY2guDQoJPiA+DQoJPiA+SSBoYXZlIGFuIGludGVy
ZmFjZSBJUGVyc2lzdGFibGUgd2l0aCAyIG1ldGhvZHMgLSBSZXRyaWV2ZQ0KYW5kIFVwZGF0ZSwg
c28NCgk+ID5teQ0KCT4gPmN1c3RvbSBjb2xsZWN0aW9ucyBpbXBsZW1lbnQgaXQuDQoJPiA+QWxz
byBteSBjdXN0b20gYnVzaW5lc3MgY29sbGVjdGlvbnMgZGVyaXZlIGZyb20NCkNvbGxlY3Rpb25C
YXNlIHVzdWFsbHkuDQoJPiA+QWxzbyBteSBlbnRpdHkgY2xhc3NlcyBhcmUgdXN1YWxseSB1c2Vk
IGFzIHByb3hpZXMgb25seSwgd2l0aA0KdGhlIElEIHNldC4NCgk+ID5JZg0KCT4gPm90aGVyIHBy
b3BlcnRpZXMgYXJlIG5lZWRlZCB0aGVuIFJldHJpZXZlIGlzIGNhbGxlZC4NCgk+ID5JIGhhdmUg
YW4gT2JqZWN0U3RhdGUgZW51bSwgd2hpY2ggY29uc2lzdHMgb2YgVW5jaGFuZ2VkLA0KSW5zZXJ0
ZWQsDQoJPiA+TW9kaWZpZWQsDQoJPiA+RGVsZXRlZCB2YWx1ZXMuIEVhY2ggYnVzaW5lc3MgZW50
aXR5IGhhcyBhbiBPYmplY3RTdGF0ZQ0KcHJvcGVydHkuIFdoZW4gSQ0KCT4gPmNhbGwgVXBkYXRl
IG9uIGEgY29sbGVjdGlvbiwgaXQgc2VyaWFsaXplcyBhbGwgdGhlIGVudGl0aWVzLA0Kd2hpY2gg
YXJlDQoJbm90DQoJPiA+dW5jaGFuZ2VkIHRvIFhNTCBhbmQgc2VuZHMgdGhpcyBYTUwgdG8gYSBz
dG9yZWQgcHJvY2VkdXJlIGluDQp0aGUgU1FMDQoJPiA+U2VydmVyLA0KCT4gPndoaWNoIHVzZXMg
T3BlblhNTCBhbmQgZXhlY3V0ZXMgdGhlIGFwcHJvcHJhdGUNCklOU0VSVC9VUERBVEUvREVMRVRF
DQoJPiA+c3RhdGVtZW50cy4NCgk+ID4NCgk+ID5JIGhhdmUgb3RoZXIgaW50ZXJmYWNlcywgd2hp
Y2ggYWxsb3cgbWUgdG8gdHJlYXQgYWxsIGJ1c2luZXNzDQplbnRpdGllcw0KCT4gPnVuaWZvcm1s
eSAuLi4NCgk+ID4NCgk+ID5JdCB3aWxsIGJlIGEgZ29vZCBkaXNjdXNzaW9uIGlmIHdlIGhlYXIg
b3RoZXIgb3BpbmlvbnMgb24NCnRoaXMgZGVzaWduLg0KCT4gPg0KCT4gPlJlZ2FyZHMsDQoJPiA+
RGV5YW4gUGV0cm92DQoJPiA+DQoJPiA+UC5TLiBUaGUgbW9zdCBpbXBvcnRhbnQgaW4gbXkgZGVz
aWduIGlzIHRoYXQgYW4NCmVudGl0eS9jb2xsZWN0aW9uIGlzDQoJPiA+dXN1YWxseQ0KCT4gPmEg
aG9sbG93IHByb3h5LCBjb25zaXN0aW5nIG9ubHkgb2YgSURzLiBJZiBvdGhlciBwcm9wZXJ0aWVz
DQphcmUgcmVxdWlyZWQsDQoJPiA+dGhlbiBhIHRyaXAgdG8gdGhlIERCIGlzIG1hZGUuDQoJPiA+
DQoJPiA+DQoJPiA+LS0tLS0gT3JpZ2luYWwgTWVzc2FnZSAtLS0tLQ0KCT4gPkZyb206ICJKYW1l
cyBZYW5nIiA8c3lhbmcxMUBiaWdwb25kLm5ldC5hdT4NCgk+ID5UbzogImFzcG5nYXJjaGl0ZWN0
dXJlIiA8YXNwbmdhcmNoaXRlY3R1cmVAYXNwZnJpZW5kcy5jb20+DQoJPiA+U2VudDogVHVlc2Rh
eSwgSnVuZSAxOCwgMjAwMiAxMjo0NiBQTQ0KCT4gPlN1YmplY3Q6IFthc3BuZ2FyY2hpdGVjdHVy
ZV0gSXMgdGhpcyBnb29kIG9iamVjdCBkZXNpZ24/Pz8NCgk+ID4NCgk+ID4NCgk+ID4gPiBDdXJy
ZW50bHksIEkgdXN1YWxseSBtYWtlIDIgb2JqZWN0cyBmb3IgMSBlbnRpdHkuLg0KCT4gPiA+DQoJ
PiA+ID4gMXN0IG9iamVjdCBpcyB0aGUgb2JqZWN0IHRoYXQgcmVwcmVzZW50cyBhIHNpbmdsZSBl
bnRpdHkNCnNvIGluIGNhc2Ugb2YNCglhDQoJPiA+ID4gcHJvZyB3aXRoIHVzZXJzLCB0aGVyZSBp
cyBhIG9iamVjdCBjYWxsZWQgIFVTRVIgYW5kDQpjb250YWlucyBtZXRob2RzDQoJPiA+bGlrZQ0K
CT4gPiA+IFVwZGF0ZSBhbmQgcHJvcGVydGllcyBvZiB1c2VyIGluZm9ybWF0aW9uIGFuZCAybmQg
b2JqZWN0DQppcyBjYWxsZWQNCglVU0VSUw0KCT4gPiA+IHdoaWNoIGlzIHRoZSBjb2xsZWN0aW9u
IG9mIFVTRVIgb2JqZWN0cyB0aGF0IGltcGxlbWVudA0KSUVudW1lcmF0b3IgYW5kDQoJPiA+ID4g
SUVudW1lcmFibGUuIGFuZCBpdCBhbHNvIGNvbnRhaW5zIG1ldGhvZHMgbGlrZSBDcmVhdGUoKQ0K
YW5kIGRlbGV0ZSgpLg0KCT4gPmFuZA0KCT4gPml0DQoJPiA+ID4gYWxzbyBoYXMgbWV0aG9kcyB0
aGF0IHJldHJpdmVzIHJlY29yZHMgZnJvbXQgaGUgZGF0YSBiYXNlDQphbmQgZmlsbCB1cA0KCT4g
PnRoZQ0KCT4gPiA+IGNvbGxlY3Rpb24gdXNpbmcgZGF0YSByZWFkZXIuLi4gSSBoYXZlIHNldmVy
YWwgb2YgdGhlc2UNCm1ldGhvZHMgYW5kDQoJdGhleQ0KCT4gPiA+IGhhdmUgZGlmZmVyZW50IGZu
cyBsaWtlIHNvcnRpbmcgZmlsdGVyaW5nIHdpdGhpbiB0aGUNCmNvbGxlY3Rpb24uLi4NCgk+ID4g
Pg0KCT4gPiA+IEkgd291bGQgdXNlIHRoZSBvYmVqY3RzIGxpa2UgdGhpcw0KCT4gPiA+DQoJPiA+
ID4gVXNlcnMgdXNlcnMgPSBuZXcgVXNlcnMoKQ0KCT4gPiA+IHVzZXJzLkdldEFsbFVzZXJzKCkN
Cgk+ID4gPiBmb3JlYWNoIChVc2VyIHVzZXIgaW4gdXNlcnMpDQoJPiA+ID4gew0KCT4gPiA+IFJl
c3BvbnNlLldyaXRlKHVzZXIuRk5hbWUpOw0KCT4gPiA+IH0NCgk+ID4gPg0KCT4gPiA+IGkgY291
bGQgYWxzbyBkbw0KCT4gPiA+DQoJPiA+ID4gdXNlcnMuR2V0VXNlcnNXaXRoRmlyc3ROYW1lKCJK
b2huIikNCgk+ID4gPg0KCT4gPiA+IEkgYWN0dWFsbHkgZG8gMSBkYXRhYmFzZSBxdWVyeSBwZXIg
R2V0X19fIG1ldGhvZHMuLg0KCT4gPiA+DQoJPiA+ID4gdGhlIHF1ZXN0aW9uIGlzLi5pcyB0aGlz
IGEgY29tbW9uIG9iamVjdCBkZXNpZ24gPyBvciBhbSBpDQpjb21wbGV0ZWx5DQoJPiA+bG9zdA0K
CT4gPiA+ID8/Pw0KCT4gPiA+DQoJPiA+ID4gUGxlYXNlIGhlbHAgbWUgb3V0ICEhIQ0KCT4gPiA+
DQoJPiA+ID4gSmFtZXMNCgk+ID4gPg0KCT4gPiA+IFBTIElmIGFueSBvbmUga25vd3MgYSBnb29k
IHNpdGUgd2l0aCBndWlkZSB0byB0aGUgb2JqZWN0DQoJZGVzaWduLi5wbGVhc2UNCgk+ID5sZXQN
Cgk+ID4gPiBtZSBrbm93Li4uDQoJPiA+ID4NCgk+ID4gPg0KCT4gPiA+DQoJPiA+ID4gfCBbYXNw
bmdhcmNoaXRlY3R1cmVdIG1lbWJlciBkZXlhbnBAaG90bWFpbC5jb20gPSBZT1VSIElEDQoJPiA+
ID4gfCBodHRwOi8vd3d3LmFzcGxpc3RzLmNvbS9hc3BsaXN0cy9hc3BuZ2FyY2hpdGVjdHVyZS5h
c3AgPQ0KSk9JTi9RVUlUDQoJPiA+ID4gfCBodHRwOi8vd3d3LmFzcGxpc3RzLmNvbS9zZWFyY2gg
PSBTRUFSQ0ggQXJjaGl2ZXMNCgk+ID4gPg0KCT4gPiA+DQoJPiA+DQoJPiA+fCBbYXNwbmdhcmNo
aXRlY3R1cmVdIG1lbWJlciBwaG90b3JlYWxtQGhvdG1haWwuY29tID0gWU9VUiBJRA0KCT4gPnwg
aHR0cDovL3d3dy5hc3BsaXN0cy5jb20vYXNwbGlzdHMvYXNwbmdhcmNoaXRlY3R1cmUuYXNwID0N
CkpPSU4vUVVJVA0KCT4gPnwgaHR0cDovL3d3dy5hc3BsaXN0cy5jb20vc2VhcmNoID0gU0VBUkNI
IEFyY2hpdmVzDQoJPiA+DQoJPg0KCT4NCgk+DQoJPg0KCT4NCl9fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fDQoJPiBTZW5kIGFu
ZCByZWNlaXZlIEhvdG1haWwgb24geW91ciBtb2JpbGUgZGV2aWNlOg0KaHR0cDovL21vYmlsZS5t
c24uY29tDQoJPg0KCT4NCgk+IHwgW2FzcG5nYXJjaGl0ZWN0dXJlXSBtZW1iZXIgZGV5YW5wQGhv
dG1haWwuY29tID0gWU9VUiBJRA0KCT4gfCBodHRwOi8vd3d3LmFzcGxpc3RzLmNvbS9hc3BsaXN0
cy9hc3BuZ2FyY2hpdGVjdHVyZS5hc3AgPQ0KSk9JTi9RVUlUDQoJPiB8IGh0dHA6Ly93d3cuYXNw
bGlzdHMuY29tL3NlYXJjaCA9IFNFQVJDSCBBcmNoaXZlcw0KCT4NCgk+DQoJDQoJfCBbYXNwbmdh
cmNoaXRlY3R1cmVdIG1lbWJlciBydXNzLm1jY2xlbGxhbmRAc21hcnRvYmp4LmNvbSA9DQpZT1VS
IElEDQoJfCBodHRwOi8vd3d3LmFzcGxpc3RzLmNvbS9hc3BsaXN0cy9hc3BuZ2FyY2hpdGVjdHVy
ZS5hc3AgPQ0KSk9JTi9RVUlUDQoJfCBodHRwOi8vd3d3LmFzcGxpc3RzLmNvbS9zZWFyY2ggPSBT
RUFSQ0ggQXJjaGl2ZXMNCgkNCgkNCg0K
Reply to this message...
 
    
Russ McClelland
aW5saW5lDQoNCgktLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLSANCglGcm9tOiBNYXRpYXMgV29s
b3NraSANCgkNCg0KCTEuIEhvdyBkbyB5b3Ugc29sdmUgdGhlIDEtdG8tbiBhbmQgbi10by1uIHJl
bGF0aW9uc2hpcHM/IEkgbWVhbiwNCnlvdSBzYWlkDQoJeW91IGhhdmUgcHJvcGVydGllcyBpbnNp
ZGUgYSBjbGFzcyB3aGljaCBob2xkcyBhbiBpbnN0YW5jZSBvZg0KYW5vdGhlciBjbGFzcywNCgls
aWtlIFVzZXJzLVJvbGUuIFRoYXQncyBvaywgYnV0IHdoYXQgYWJvdXQgdHJhbnNhY3Rpb25zIGlu
IHRoaXMNCmNvbnRleHQ/IEZvcg0KCWluc3RhbmNlLCBpZiBhbiBPcmRlciBpcyBkZWxldGVkLCBh
bGwgaXRzIEl0ZW1zIG5lZWQgdG8gYmUNCmRlbGV0ZWQuIEhvdyBkbw0KCXlvdSBtYW5hZ2UgdG8g
ZG8gdGhhdCBpbiBhIHdob2xlIHRyYW5zYWN0aW9uIGFuZCBjb21taXQgaXQgb3INCnJvbGxiYWNr
IGl0Pw0KCQ0KDQoJQS4gIE90aGVyIG9iamVjdHMgaW4gdGhlIHByb2JsZW0gZG9tYWluIGFyZSBu
YXR1cmFsIHBsYWNlcyB0bw0KcHV0IHRoZXNlIGFnZ3JlZ2F0aW9uIHJlbGF0aW9uc2hpcHMuICBU
byBoYW5kbGUgdHJhbnNhY3Rpb25zLCB5b3UgY2FuDQp1c2UgTVRTIG9yIHlvdSBjYW4gbWFudWFs
bHkgc3RhcnQgYW5kIHN0b3AgeW91ciB0cmFuc2FjdGlvbiAoaWUuIGJlZ2luDQp0aGUgdHhuIHdo
ZW4geW91IHdyaXRlIHRoZSAiYWdncmVnYXRvciIgYW5kIGNsb3NlIHRoZSB0eG4gYWZ0ZXIgeW91
IGxvb3ANCnRocm91Z2ggdGhlICJhZ2dyZWdhdGVzIi4NCg0KCQ0KDQoJMi4gRG8geW91IGhhdmUg
c29tZSBzYW1wbGUgY29kZSBhYm91dCBob3cgZG8geW91IHNlcmlhbGl6ZSB5b3VyDQpjbGFzcyBp
bg0KCXhtbD8NCg0KCQ0KCUEuICBMb29rIGF0IHRoZSBYbWxTZXJpYWxpemVyIGNsYXNzLiAgSG93
ZXZlciwgaWYgeW91IHdhbnQgdmVyeQ0Kc2ltcGxlIFhtbCBzZXJpYWxpemF0aW9uIGZyb20gYSB3
ZWIgc2VydmljZSBtZXRob2QsIC5OZXQgaGFuZGxlcyB0aGF0DQpmb3IgeW91LiAgQ2hhbmdlIHRo
ZSByZXR1cm4gdHlwZSBvZiB5b3VyIFdlYiBTZXJ2aWNlIG1ldGhvZCB0byByZXR1cm4NCnlvdXIg
b2JqZWN0LiAgTWFyayB5b3VyIG9iamVjdCBhcyBbU2VyaWFsaXphYmxlXS4gIFRoZSB3ZWIgc2Vy
dmljZSB3aWxsDQphdXRvbWF0aWNhbGx5IGludm9rZSB0aGUgWG1sU2VyaWFsaXplciBvbiB5b3Vy
IGJlaGFsZg0KDQoJMy4gVGhlIGRhdGFib3VuZCBjb250cm9scyBoYXMgc3VwcG9ydCBmb3IgY2xh
c3NlcyBpbXBsZW1lbnRpbmcNCklFbnVtZXJhdG9yDQoJYW5kIElFbnVtZXJhYmxlPyBJIG1lYW4g
eW91IGNhbiBiaW5kIGEgQ29sbGVjdGlvbiB0byBhIERhdGFncmlkDQp0aGUgc2FtZSB3YXkNCgl5
b3UgZG8gaXQgd2l0aCBhIERhdGFzZXQ/IFdoaWNoIGFyZSB0aGUgdGhpbmdzIHlvdSBsb29zZSB3
aGVuDQp1c2luZw0KCUNvbGxlY3Rpb25zIHZzLiBEYXRhc2V0cz8NCg0KCUEuICBZb3UgZG9uJ3Qg
bG9vc2UgYW55dGhpbmcuICBXZSBiaW5kIHRvIGNvbGxlY3Rpb25zIG9mIGRvbWFpbg0Kb2JqZWN0
cyBhbGwgdGhlIHRpbWUuICBXZWxsLCBJIHN1cHBvc2UgaWYgeW91IHVzZSBkYXRhIGJpbmRpbmcg
dG8NCmF1dG9tYXRpY2FsbHkgZG8gZWRpdHRpbmcgYW5kIHVwZGF0ZXMsIHlvdSdkIGxvb3NlIHRo
YXQuICBTaW5jZSB3ZSB0cmVhdA0KcGVyc2lzdGVuY2UgYXMgYSBzZXJ2aWNlLCB3ZSBkb24ndCBt
aXNzIHRoYXQuDQoJDQoNCg=
Reply to this message...
 
    
Mark Feinholz
Russ/Deyan

Have you come up with a pattern that allows you to load a hierarchy of
collections all at once - I.E. does your service layer have the ability to
run a load proc at the 'top' of the hierarchy that returns multiple rowsets
and dynamically decide which child collection objects need to be
instanciated? Or is each child in the hierarchy created and loaded with
data as it is needed with separate calls to the db?

And then when it comes time to save the hierarchy back to the database
(inserts, deletes, updates) does the service layer take a serialized version
of all of the objects in the hierarchy and handle the transacted update, or
do the application objects each have to make sure they get themselves saved
- which means the transaction boundary has to live across multiple calls to
the service object?

I am also trying to come up with the object architecture for my first .Net
system!

One of my issues is my application will be delivered both as a browser based
app and as a thick client WinForm based app backed by WebServices.

So this means that my persist service layer will have to be wrapped in a Web
Service.

Another Issue I am struggling with is it really feels like I should be
taking advantage of Typed DataSets to perform alot of the work (Updates,
dealing with returning new identity keys, cascading those new keys to
children, etc) of the service layer. I think I am hearing from you 2 that
your approaches are not based on any of the built in functionality of
DataAdapters and DataSets???

One more thought... If you have got an object, Say User, that has a list of
Roles that the User is a member of, and you have got a UI need to simply
display all of the properties of the User along with a ListBox showing the
Roles - it sure does seem like overkill to have to load up the collection of
Roles objects instead of the User property simply exposing an ArrayList of
Roles that can of course be bound to the UI control. But again this means
that when you load the User object, you need multiple rowsets from the db,
one for the User and one for the list of Roles and the Service layer would
have to be capable of handling that. Does your design allow for "breaking"
the rules - or is this type of performance concern simply not been a
problem?

This is a great discussion.

Mark.

-----Original Message-----
From: Russ McClelland [mailto:Click here to reveal e-mail address]
Sent: Wednesday, June 19, 2002 7:09 AM
To: aspngarchitecture
Subject: RE: [aspngarchitecture] RE: Is this good object design???

inline

-----Original Message-----
From: Matias Woloski

1. How do you solve the 1-to-n and n-to-n relationships? I mean, you said
you have properties inside a class which holds an instance of another class,
like Users-Role. That's ok, but what about transactions in this context? For
instance, if an Order is deleted, all its Items need to be deleted. How do
you manage to do that in a whole transaction and commit it or rollback it?

A. Other objects in the problem domain are natural places to put these
aggregation relationships. To handle transactions, you can use MTS or you
can manually start and stop your transaction (ie. begin the txn when you
write the "aggregator" and close the txn after you loop through the
"aggregates".

2. Do you have some sample code about how do you serialize your class in
xml?

A. Look at the XmlSerializer class. However, if you want very simple Xml
serialization from a web service method, .Net handles that for you. Change
the return type of your Web Service method to return your object. Mark your
object as [Serializable]. The web service will automatically invoke the
XmlSerializer on your behalf

3. The databound controls has support for classes implementing IEnumerator
and IEnumerable? I mean you can bind a Collection to a Datagrid the same way
you do it with a Dataset? Which are the things you loose when using
Collections vs. Datasets?

A. You don't loose anything. We bind to collections of domain objects all
the time. Well, I suppose if you use data binding to automatically do
editting and updates, you'd loose that. Since we treat persistence as a
service, we don't miss that.
Reply to this message...
 
    
Deyan Petrov
Hi Mark,

My design works as follows...
When you have a SINGLE entity and you want to Retrieve or Update it from/to
the DB, then this is done using 2 stored procedures - for select and update
respectively.
When you have a custom COLLECTION of entities and you want to Retrieve or
Update it, then the collection is treated as a set and the methods operate
on a set, that is - when Retrieving, the stored procedures returns a
IDataReader, which is iterated and the entities in the set are created. When
you call Update on a collection, then it examines its entities, decides
which are to be inserted or modified and calles the appropriate sproc(or
sprocs), and which should be deleted - in this case only the ids are passed
to another sproc.
So in case you have an Entity, which in turn has a collection of other
entities as a property, then dynamically the entity retrieves its
properties, if necessary, and the collection, which is also a property,
retrieves itself, when necessary.
I don't like very much the DataAdapters and the DataSets. I think the
DataSet internally iterates over a IDataReader and fills itself. Also when
the DataSet is passed to the DB by the means of a DataAdapter, the
DataAdapter inspect the State of each row and calls the appropriate SQL
statement/sproc for EACH individual row. This might result in hundreds of
roundtrips to the DB.
In contrast my custom collections are smart enough to decide whether they
should serialize the objects and call a sproc with NTEXT parameter and
OpenXML, or should execute a sproc for each entity.
Internally my custom collections use ArrayLists usually. So it's almost the
same (from performance point of view) whether you will fill an ArrayList, or
my custom collection with id/name pairs, to be rendered in the interface.
As I mentioned, I have written a Data Access Component, which is able to
span transactions accross multiple method calls, so I have solved this way
my transaction problems ;)

Pfuuu, too much writing is not healthy ;)

Regards,
Deyan Petrov

----- Original Message -----
From: "Mark Feinholz" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 7:41 PM
Subject: [aspngarchitecture] RE: Is this good object design???

Russ/Deyan

Have you come up with a pattern that allows you to load a hierarchy of
collections all at once - I.E. does your service layer have the ability to
run a load proc at the 'top' of the hierarchy that returns multiple rowsets
and dynamically decide which child collection objects need to be
instanciated? Or is each child in the hierarchy created and loaded with
data as it is needed with separate calls to the db?

And then when it comes time to save the hierarchy back to the database
(inserts, deletes, updates) does the service layer take a serialized version
of all of the objects in the hierarchy and handle the transacted update, or
do the application objects each have to make sure they get themselves saved
- which means the transaction boundary has to live across multiple calls to
the service object?

I am also trying to come up with the object architecture for my first .Net
system!

One of my issues is my application will be delivered both as a browser based
app and as a thick client WinForm based app backed by WebServices.

So this means that my persist service layer will have to be wrapped in a Web
Service.

Another Issue I am struggling with is it really feels like I should be
taking advantage of Typed DataSets to perform alot of the work (Updates,
dealing with returning new identity keys, cascading those new keys to
children, etc) of the service layer. I think I am hearing from you 2 that
your approaches are not based on any of the built in functionality of
DataAdapters and DataSets???

One more thought... If you have got an object, Say User, that has a list of
Roles that the User is a member of, and you have got a UI need to simply
display all of the properties of the User along with a ListBox showing the
Roles - it sure does seem like overkill to have to load up the collection of
Roles objects instead of the User property simply exposing an ArrayList of
Roles that can of course be bound to the UI control. But again this means
that when you load the User object, you need multiple rowsets from the db,
one for the User and one for the list of Roles and the Service layer would
have to be capable of handling that. Does your design allow for "breaking"
the rules - or is this type of performance concern simply not been a
problem?

This is a great discussion.

Mark.

-----Original Message-----
From: Russ McClelland [mailto:Click here to reveal e-mail address]
Sent: Wednesday, June 19, 2002 7:09 AM
To: aspngarchitecture
Subject: RE: [aspngarchitecture] RE: Is this good object design???

inline

-----Original Message-----
From: Matias Woloski

1. How do you solve the 1-to-n and n-to-n relationships? I mean, you said
you have properties inside a class which holds an instance of another class,
like Users-Role. That's ok, but what about transactions in this context? For
instance, if an Order is deleted, all its Items need to be deleted. How do
you manage to do that in a whole transaction and commit it or rollback it?

A. Other objects in the problem domain are natural places to put these
aggregation relationships. To handle transactions, you can use MTS or you
can manually start and stop your transaction (ie. begin the txn when you
write the "aggregator" and close the txn after you loop through the
"aggregates".

2. Do you have some sample code about how do you serialize your class in
xml?

A. Look at the XmlSerializer class. However, if you want very simple Xml
serialization from a web service method, .Net handles that for you. Change
the return type of your Web Service method to return your object. Mark your
object as [Serializable]. The web service will automatically invoke the
XmlSerializer on your behalf

3. The databound controls has support for classes implementing IEnumerator
and IEnumerable? I mean you can bind a Collection to a Datagrid the same way
you do it with a Dataset? Which are the things you loose when using
Collections vs. Datasets?

A. You don't loose anything. We bind to collections of domain objects all
the time. Well, I suppose if you use data binding to automatically do
editting and updates, you'd loose that. Since we treat persistence as a
service, we don't miss that.

----------------------------------------------------------------------------
----

[Original message clipped]

Reply to this message...
 
    
Brian Espey
[Original message clipped]

Deyan,

I wouldn't think the DataSet internally iterates over
an IDataReader, because it's a totally disconnected,
independent "value object". if anything, the adapter
would iterate over the datareader and fill the dataset
when you call DataAdapter.Fill. a dataset isn't
responsible for filling itself.

Brian

[Original message clipped]


__________________________________________________
Do You Yahoo!?
Yahoo! - Official partner of 2002 FIFA World Cup
http://fifaworldcup.yahoo.com

Reply to this message...
 
    
Mark Feinholz
Dyan,

Thanks very much for taking the time to write all that down. You've
made it very clear how it all works (except for that mysterious data
access component that manages transactions across method calls - That
doesn't sound stateless enough for me).

I'm not ready to give up on DataSets yet though! Only experience will
tell, but it 'feels' like they will provide the perfect mechanism to
remote the persist service layer via a Web Service so that my objects
will also work on a fat 32 bit client installation of the application.

Without having hashed out the details yet, it makes sense to me that the
fat client should be able to take one trip over the wire to grab all of
the data it will need for the entire hierarchy of objects that it will
be working with, instead of each object/object collection in the
hierarchy having to go back over the wire to get more data. This same
approach would also work of course for the WebForm client.

Then you reverse the process, sending the dataset back all at once to
perform the transacted update.

Sounds too easy, nothing done right comes that easy! I need to work out
the details.

As far as your approach for sending a chunk of XML to a proc, you can
accomplish that exact same thing with a DataSet, just serialize the
updated data in the dataset to xml and run your proc - don't use the
update method of a dataAdapter.

Thanks again for the time you've spent on this discussion.

Mark.

-----Original Message-----
From: Deyan Petrov [mailto:Click here to reveal e-mail address]
Sent: Wednesday, June 19, 2002 11:47 AM
To: aspngarchitecture
Subject: [aspngarchitecture] RE: Is this good object design???

Hi Mark,

My design works as follows...

When you have a SINGLE entity and you want to Retrieve or Update it
from/to
the DB, then this is done using 2 stored procedures - for select and
update
respectively.

When you have a custom COLLECTION of entities and you want to Retrieve
or
Update it, then the collection is treated as a set and the methods
operate
on a set,

that is - when Retrieving, the stored procedures returns a
IDataReader, which is iterated and the entities in the set are created.

When you call Update on a collection, then it examines its entities,
decides
which are to be inserted or modified and calles the appropriate sproc(or
sprocs), and which should be deleted - in this case only the ids are
passed
to another sproc.

So in case you have an Entity, which in turn has a collection of other
entities as a property, then dynamically the entity retrieves its
properties, if necessary, and the collection, which is also a property,
retrieves itself, when necessary.

I don't like very much the DataAdapters and the DataSets.

I think the DataSet internally iterates over a IDataReader and fills
itself. Also when
the DataSet is passed to the DB by the means of a DataAdapter, the
DataAdapter inspect the State of each row and calls the appropriate SQL
statement/sproc for EACH individual row. This might result in hundreds
of
roundtrips to the DB.

In contrast my custom collections are smart enough to decide whether
they
should serialize the objects and call a sproc with NTEXT parameter and
OpenXML, or should execute a sproc for each entity.

Internally my custom collections use ArrayLists usually. So it's almost
the
same (from performance point of view) whether you will fill an
ArrayList, or
my custom collection with id/name pairs, to be rendered in the
interface.

As I mentioned, I have written a Data Access Component, which is able to
span transactions accross multiple method calls, so I have solved this
way
my transaction problems ;)

Pfuuu, too much writing is not healthy ;)

Regards,
Deyan Petrov

----- Original Message -----
From: "Mark Feinholz" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Wednesday, June 19, 2002 7:41 PM
Subject: [aspngarchitecture] RE: Is this good object design???

Russ/Deyan

Have you come up with a pattern that allows you to load a hierarchy of
collections all at once - I.E. does your service layer have the ability
to
run a load proc at the 'top' of the hierarchy that returns multiple
rowsets
and dynamically decide which child collection objects need to be
instanciated? Or is each child in the hierarchy created and loaded with
data as it is needed with separate calls to the db?

And then when it comes time to save the hierarchy back to the database
(inserts, deletes, updates) does the service layer take a serialized
version
of all of the objects in the hierarchy and handle the transacted update,
or
do the application objects each have to make sure they get themselves
saved
- which means the transaction boundary has to live across multiple calls
to
the service object?

I am also trying to come up with the object architecture for my first
.Net
system!

One of my issues is my application will be delivered both as a browser
based
app and as a thick client WinForm based app backed by WebServices.

So this means that my persist service layer will have to be wrapped in a
Web
Service.

Another Issue I am struggling with is it really feels like I should be
taking advantage of Typed DataSets to perform alot of the work (Updates,
dealing with returning new identity keys, cascading those new keys to
children, etc) of the service layer. I think I am hearing from you 2
that
your approaches are not based on any of the built in functionality of
DataAdapters and DataSets???

One more thought... If you have got an object, Say User, that has a
list of
Roles that the User is a member of, and you have got a UI need to simply
display all of the properties of the User along with a ListBox showing
the
Roles - it sure does seem like overkill to have to load up the
collection of
Roles objects instead of the User property simply exposing an ArrayList
of
Roles that can of course be bound to the UI control. But again this
means
that when you load the User object, you need multiple rowsets from the
db,
one for the User and one for the list of Roles and the Service layer
would
have to be capable of handling that. Does your design allow for
"breaking"
the rules - or is this type of performance concern simply not been a
problem?

This is a great discussion.

Mark.

-----Original Message-----
From: Russ McClelland [mailto:Click here to reveal e-mail address]
Sent: Wednesday, June 19, 2002 7:09 AM
To: aspngarchitecture
Subject: RE: [aspngarchitecture] RE: Is this good object design???

inline

-----Original Message-----
From: Matias Woloski

1. How do you solve the 1-to-n and n-to-n relationships? I mean, you
said
you have properties inside a class which holds an instance of another
class,
like Users-Role. That's ok, but what about transactions in this context?
For
instance, if an Order is deleted, all its Items need to be deleted. How
do
you manage to do that in a whole transaction and commit it or rollback
it?

A. Other objects in the problem domain are natural places to put these
aggregation relationships. To handle transactions, you can use MTS or
you
can manually start and stop your transaction (ie. begin the txn when you
write the "aggregator" and close the txn after you loop through the
"aggregates".

2. Do you have some sample code about how do you serialize your class in
xml?

A. Look at the XmlSerializer class. However, if you want very simple
Xml
serialization from a web service method, .Net handles that for you.
Change
the return type of your Web Service method to return your object. Mark
your
object as [Serializable]. The web service will automatically invoke the
XmlSerializer on your behalf

3. The databound controls has support for classes implementing
IEnumerator
and IEnumerable? I mean you can bind a Collection to a Datagrid the same
way
you do it with a Dataset? Which are the things you loose when using
Collections vs. Datasets?

A. You don't loose anything. We bind to collections of domain objects
all
the time. Well, I suppose if you use data binding to automatically do
editting and updates, you'd loose that. Since we treat persistence as a
service, we don't miss that.

------------------------------------------------------------------------
----
----

[Original message clipped]

| [aspngarchitecture] member Click here to reveal e-mail address = YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp = JOIN/QUIT
| http://www.asplists.com/search = SEARCH Archives

Reply to this message...
 
    
Russ McClelland
LS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0gDQpGcm9tOiBNYXJrIEZlaW5ob2x6IA0KDQpUaGFu
a3MgdmVyeSBtdWNoIGZvciB0YWtpbmcgdGhlIHRpbWUgdG8gd3JpdGUgYWxsIHRoYXQgZG93bi4g
IFlvdSd2ZQ0KbWFkZSBpdCB2ZXJ5IGNsZWFyIGhvdyBpdCBhbGwgd29ya3MgKGV4Y2VwdCBmb3Ig
dGhhdCBteXN0ZXJpb3VzIGRhdGENCmFjY2VzcyBjb21wb25lbnQgdGhhdCBtYW5hZ2VzIHRyYW5z
YWN0aW9ucyBhY3Jvc3MgbWV0aG9kIGNhbGxzIC0gVGhhdA0KZG9lc24ndCBzb3VuZCBzdGF0ZWxl
c3MgZW5vdWdoIGZvciBtZSkuDQoNCg0KW1J1c3NdIERvbid0IGNvbmZ1c2UgbWV0aG9kIGNhbGxz
IHdpdGggdHJhbnNhY3Rpb24gYm91bmRhcmllcyBvciBuZXR3b3JrDQp0cmlwcy4gIFlvdSBjYW4g
bWFrZSBzZXZlcmFsIG1ldGhvZCBjYWxscyAid2l0aGluIiBhIGNvbXBvbmVudCBpZiB5b3UNCnN0
YXJ0IHdpdGggYSBoaWdoZXIgbGV2ZWwgaW50ZXJmYWNlIHRoYXQgYWNjZXB0cyBtb3JlIGNvbXBs
ZXggbW9kZWxzIHRvDQp3b3JrIG9uLiAgSW4gdGhlIGNhc2Ugb2Ygb3VyIHBlcnNpc3RlbmNlIGxh
eWVyLCB3ZSBtYXkgYWNjZXB0IGEgY29tcGxldGUNCk9yZGVyIG9iamVjdCB3aXRoIGFsbCBpdHMg
bGluZSBpdGVtcyBpbiBvbmUgbWV0aG9kIGNhbGwgYW5kIG9uZSBuZXR3b3JrDQp0cmlwLiAgVGhl
IHBlcnNpc3RlbmNlIGNvbXBvbmVudCB0aGVuIGRlY29tcG9zZXMgdGhlIG9iamVjdCBhbmQgbWFr
ZXMNCmNhbGxzICh0byBpdHNlbGYgb3IgYW5vdGhlciBwZXJzaXN0ZW5jZSBvYmplY3QpIHRvIGhh
bmRsZSBzYXZpbmcgdGhlDQpvcmRlciBkYXRhIGFuZCB0aGVuIHRoZSBsaW5lIGl0ZW0gZGF0YSAo
dXN1YWxseSBtb2RlbGxlZCBpbiB0d28gc2VwYXJhdGUNCnRhYmxlcykuICBUaGUgYmFjayBlbmQg
cGllY2UgdG8gdGhlIGRhdGFiYXNlIGlzIG11bHRpcGxlIG5ldHdvcmsgdHJpcHMsDQpidXQgdGhl
IGNsaWVudCBvbmx5IG1ha2VzIG9uZSB0cmlwIHRvIHRoZSBzZXJ2ZXIuICBJZiBTUUwgU2VydmVy
IGhhbmRsZWQNCmNvbXBsZXggZGF0YSB0eXBlcyAod2FpdGluZyB3aXRoIGJhaXRlZCBicmVhdGgg
Zm9yIFl1a29uKSwgdGhpcyBtb2RlbA0KY2FuIGVhc2lseSBjaGFuZ2UgdG8gc3VwcG9ydCBzaW5n
bGUgdHJpcHMgdG8gdGhlIGRhdGFiYXNlIGFzIHdlbGwuDQoNCg0KSSdtIG5vdCByZWFkeSB0byBn
aXZlIHVwIG9uIERhdGFTZXRzIHlldCB0aG91Z2ghICBPbmx5IGV4cGVyaWVuY2Ugd2lsbA0KdGVs
bCwgYnV0IGl0ICdmZWVscycgbGlrZSB0aGV5IHdpbGwgcHJvdmlkZSB0aGUgcGVyZmVjdCBtZWNo
YW5pc20gdG8NCnJlbW90ZSB0aGUgcGVyc2lzdCBzZXJ2aWNlIGxheWVyIHZpYSBhIFdlYiBTZXJ2
aWNlIHNvIHRoYXQgbXkgb2JqZWN0cw0Kd2lsbCBhbHNvIHdvcmsgb24gYSBmYXQgMzIgYml0IGNs
aWVudCBpbnN0YWxsYXRpb24gb2YgdGhlIGFwcGxpY2F0aW9uLg0KDQoNCltSdXNzXSAgT3VyIHdo
b2xlIHByb2JsZW0gd2l0aCB0aGlzIGlzIHRoYXQgd2Ugb2Z0ZW4gcmV1c2VzIGNsYXNzZXMgZnJv
bQ0KdGhlIGRvbWFpbiBjb21wb25lbnRzIGluIGFwcGxpY2F0aW9ucyB3aGVyZSBwZXJzaXN0ZW5j
ZSBpcyBub3QgcmVxdWlyZWQuDQpGb3IgaW5zdGFuY2UgYSBFbXBsb3llZSBjbGFzcyBpbiBzZXZl
cmFsIGFwcGxpY2F0aW9ucyByZXF1aXJlcyB1cGRhdGVzDQpldGMsIGJ1dCB0aGUgY2xhc3MgY2Fu
IGFsc28gYmUgdXNlZCBpbiBhIHRyYW5zaWVudCBmYXNoaW9uIGluIGRvemVucyBvZg0Kb3RoZXIg
YXBwbGljYXRpb25zLiAgQ29kaW5nIHlvdXIgZGF0YSBhY2Nlc3MgaW4gdGhlIEVtcGxveWVlIGNs
YXNzIChpZSwNClNhdmUoKSwgVXBkYXRlKCksIGV0YykgKnJlcXVpcmVzKiB0aGF0IGNsYXNzIHRv
IGJlIHBlcnNpc3RlbmNlIGF3YXJlDQpldmVuIGlmIHRoZSBhcHBsaWNhdGlvbiBoYXMgbm8gbmVl
ZCBmb3IgcGVyc2lzdGVuY2UuICBXaGF0J3MgbW9yZSwgd2UndmUNCnJ1biBpbnRvIGNvbXBvbmVu
dHMgZGV2ZWxvcGVkIGVhcmxpZXIgd2hlcmUgcGVyc2lzdGVuY2Ugd2FzICJ0cmlnZ2VyZWQiDQp3
aGVuIHdlIGNhbGxlZCBhbiBpbm5vY3VvdXMgbWV0aG9kIGFuZCB0aGVuIChvZiBjb3Vyc2UpIHRo
cmV3IGFuDQpleGNlcHRpb24gYmVjYXVzZSB0aGUgREIgY29ubmVjdGlvbiBzZXR0aW5ncyAoZXRj
KSB3ZXJlIG5vdCBzZXQgdXANCmNvcnJlY3RseS4gDQoNCldlIGFsc28gbmVlZCB0byBzd2FwIGRh
dGFiYXNlcyAod2UgYXJlIGEgY29uc3VsdGluZyBjb21wYW55KSBmb3IgdGhlDQpzYW1lIHByb2R1
Y3QgYmV0d2VlbiBvdXIgY2xpZW50cy4gIFdoaWxlIHRoZSBkYXRhIGFjY2VzcyBsaWJyYXJpZXMg
Z28gYQ0KbG9uZyB3YXkgaW4gZGVhbGluZyB3aXRoIHRoaXMgaXNzdWUsIHRyZWF0aW5nIHBlcnNp
c3RlbmNlIGFzIGEgc2VwYXJhdGUNCnNlcnZpY2UgYWxsb3dzIHVzIHRvIHJld3JpdGUgYSBmZXcg
Y2xhc3NlcyB0byB0YWtlIGFkdmFudGFnZSBvZiB0aGUgbmV3DQpEQiB3aXRob3V0IGNsb3VkaW5n
IHVwIHRoZSBkb21haW4gY29tcG9uZW50cy4NCg0KWy9SdXNzXQ0KDQogDQoNCg=
Reply to this message...
 
    
Francesco Sanfilippo
So if I go to the pure OO, non data-centric, approach, and use objects for
each relationship between Person and Category, and have collections of
PersonCategory relationships, where is the collection stored, and desn't it
have to be a data structure to hold the individual objects?

FS

[Original message clipped]

_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.

Reply to this message...
 
    
Deyan Petrov
You shouldn't have collections of PersonCategory relationships. I don't
understand what this Category objects stands for and what is it's
relationship to a Person, but you can just use composition to have
Categories property of a Person object or vice versa.
Where is the collection stored? Where are the DataRows stored? ;)
Internal ArrayList for examle, whatever, wherever ;)

Regards,
Deyan Petrov

----- Original Message -----
From: "Francesco Sanfilippo" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Friday, June 21, 2002 12:04 AM
Subject: [aspngarchitecture] Re: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Francesco Sanfilippo
OK, look...

A PersonCategory relationship defines a category that a person has chosen to
be associated with. There are Person, Category, and PersonCategory tables
in the database. I think you're saying I should not have a PersonCategory
object because that kind of data should not be cached or stored in Session,
am I right?

FS

[Original message clipped]

_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.

Reply to this message...
 
    
Rich Denis
In my experience, generally mapping tables do not have their own classes
associated with them. They are generally a collection of one or the
other objects sometimes both. It all depends, but based on the limited
knowledge of what you are trying to accomplish I would first guess that
a Person has a categories collection off of it. No need for the person
Category Mapping object.

-----Original Message-----
From: Francesco Sanfilippo [mailto:Click here to reveal e-mail address]=20
Sent: Friday, June 21, 2002 12:00 PM
To: aspngarchitecture
Subject: [aspngarchitecture] Re: Is this good object design???

OK, look...

A PersonCategory relationship defines a category that a person has
chosen to=20
be associated with. There are Person, Category, and PersonCategory
tables=20
in the database. I think you're saying I should not have a
PersonCategory=20
object because that kind of data should not be cached or stored in
Session,=20
am I right?

FS

[Original message clipped]


[Original message clipped]

_________________________________________________________________
Get your FREE download of MSN Explorer at
http://explorer.msn.com/intl.asp.

| [aspngarchitecture] member Click here to reveal e-mail address =3D YOUR ID=20
| http://www.asplists.com/asplists/aspngarchitecture.asp =3D JOIN/QUIT=20
| http://www.asplists.com/search =3D SEARCH Archives

Reply to this message...
 
    
Andy Smith
A single array or simple collection isn't good enough if you want to do =
complicated things like be able to temporarily remove items from the =
collection, or mark an item in the collection as changed, or other such =
things.
=20

__
Andy Smith
Keyboard Jockey #3

[Original message clipped]

Reply to this message...
 
    
Rich Denis
I don't disagree with that. But whatever that object representation is
could be part and parcel of the container object. You can have your
complex collection still be a property off of Person right?

-----Original Message-----
From: Andy Smith [mailto:Click here to reveal e-mail address]=20
Sent: Friday, June 21, 2002 1:06 PM
To: aspngarchitecture
Subject: [aspngarchitecture] Re: Is this good object design???

A single array or simple collection isn't good enough if you want to do
complicated things like be able to temporarily remove items from the
collection, or mark an item in the collection as changed, or other such
things.
=20

__
Andy Smith
Keyboard Jockey #3

[Original message clipped]

| [aspngarchitecture] member Click here to reveal e-mail address =3D YOUR ID=20
| http://www.asplists.com/asplists/aspngarchitecture.asp =3D JOIN/QUIT=20
| http://www.asplists.com/search =3D SEARCH Archives

Reply to this message...
 
    
Andy Smith
If one were to go the non-dataset path, A common structure might be a =
Person object, a Category object and a PersonCategoryCollection object. =
each person would have a Categories property which is an instance of the =
PersonCategoryCollection. this collection would manage the "mappings" =
table.

The weird thing is going to be that you have to know that changing the =
properties of a Category changes those properties for all people that =
use that Category. not very obvious behavior.

__
Andy Smith
Keyboard Jockey #3

[Original message clipped]

Reply to this message...
 
    
Matias Woloski
Hi Deyan and all,
I have two issues for you:

1.
imagine you have a Person class. Inside Person you have the Name, Age, and
some other properties and also a Phones collection, Addresses collection and
Orders collection. And inside Orders collection there is a property
OrderDetails, which is a collection of Items. You get the idea.

Person
    PersonId
    Name
    Age
    Phones
        Phone
    Addresses
        Address
    Orders
        Order
            Items
                Item

So every time you Retrieve a Person you should be loading all its hierarchy.
Imagine if you have a collection of Persons.

2.
You have a datagrid where you show the Name, Age and Phones of a Person. Now
you made some changes on some records. According to your design the person
object will be serialized into xml and passed to an sp where you use
OpenXML. That sounds good.
But this time I'll have an xml serialized like this one
<Persons>
    <Person status="changed">
        <PersonId>1</PersonId>
        <Name>Magoo</Name>
        <Age>90</Age>
        <Phones>
            <Phone status="changed">
                <PhoneId>1</PhoneId>
                <PersonId>1<PersonId>
                <Number>999-9999-999</Number>
            </Phone>
            <Phone status="">
                <PhoneId>2</PhoneId>
                <PersonId>1<PersonId>
                <Number>991-9999-999</Number>
            </Phone>
            <Phone status="new">
                <PhoneId></PhoneId>
                <PersonId>1<PersonId>
                <Number>991-9999-999</Number>
            </Phone>
        </Phones>
    </Person>
    <Person status="deleted">
        <PersonId>2</PersonId>
        <Name>Magoo2</Name>
        <Age>9</Age>
        <Phones>
            <Phone status="">
                <PhoneId>4</PhoneId>
                <PersonId>2<PersonId>
                <Number>999-9999-999</Number>
            </Phone>
        </Phones>
    </Person>
    <Person status="new">
        <PersonId></PersonId>
        <Name>MagooNew</Name>
        <Age>90</Age>
        <Phones>
            <Phone status="new">
                <PhoneId></PhoneId>
                <PersonId><PersonId>
                <Number>999-9999-999</Number>
            </Phone>
        </Phones>
    </Person>
</Persons>

This is the XML serialized from the Person class, at least this is the idea
in my mind.
How do you manage this three cases in your sp? especially the 'new' case.
It's necessary to know the PersonId to insert the Phone with the PersonId
field as foreign key.

ok... that's all
thanks in advance! great discussion

Matias

[Original message clipped]

Reply to this message...
 
    
Francesco Sanfilippo
Complex collection? You mean like a DataTable or DataSet, right?

FS

[Original message clipped]

_________________________________________________________________
MSN Photos is the easiest way to share and print your photos:
http://photos.msn.com/support/worldwide.aspx

Reply to this message...
 
    
Rich Denis
One that has other methods and properties in it to do things other than
iterate, add, del etc. Like Andy said, keep track of changes etc.

-----Original Message-----
From: Francesco Sanfilippo [mailto:Click here to reveal e-mail address]=20
Sent: Friday, June 21, 2002 2:13 PM
To: aspngarchitecture
Subject: [aspngarchitecture] Re: Is this good object design???

Complex collection? You mean like a DataTable or DataSet, right?

FS

[Original message clipped]


[Original message clipped]


[Original message clipped]

_________________________________________________________________
MSN Photos is the easiest way to share and print your photos:=20
http://photos.msn.com/support/worldwide.aspx

| [aspngarchitecture] member Click here to reveal e-mail address =3D YOUR ID=20
| http://www.asplists.com/asplists/aspngarchitecture.asp =3D JOIN/QUIT=20
| http://www.asplists.com/search =3D SEARCH Archives

Reply to this message...
 
    
Andy Smith
actually, i _was_ hinting towards using the dataset.

I'm a major proponent of the Typed DataSet as a middle-layer component.

If you want to encapsulate the Typed DataSet with some kind engine or =
simpler interface, that's great, but I think that all of these =
concurrency, change tracking, and relationship issues have _already been =
solved_ and there's no need to reimplement them.

__
Andy Smith
Keyboard Jockey #3

[Original message clipped]

Reply to this message...
 
    
Francesco Sanfilippo
So you think my initial idea (which was the original post in this thread) of
using a DataTable or DataSet, which would be a property of a Person object,
as a temp cache of user-specific data is sound?

I really want to store these Person objects in Session, to minimize DB
traffic as much as possible. I have 4GB of RAM to burn, and want to speed
up performance as much as possible. The DB trip always seems to be the
biggest bottleneck.

FS

[Original message clipped]

_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com/intl.asp.

Reply to this message...
 
    
Andy Smith
i've not done any real perf numbers here...
( truthfully, i've never had a NEED to worry about perf on any of my web =
apps )

but Andy's Law of Performance is
do the Easy Thing first, and if perf isn't good enough, tweak where =
neccesary.

this is especially true if you aren't worrying about scalability.
( which i got from the ram comment )

so my opinion would be that the Person object IS a table in a strongly =
typed dataset.
Maybe have a "SiteCustomization" ( or whatever ) DataSet containing the =
PeopleTable and CategoryTable and any other tables and relationships =
required for the task. you could maybe wrap it with a thin engine that =
knows when to populate the data from the datasource, maybe some tables =
need instant population, other tables only need to be accessed as asked =
for.

__
Andy Smith
Keyboard Jockey #3

[Original message clipped]

Reply to this message...
 
    
Chris Tinsley
Francesco,
The approach we took may not be the best, but it would probably fit in
your situation. We too wanted a way to store business entities in
session in order to avoid excessive calls to the db. We did a hybrid of
many of the designs explained in this thread. We use Typed DataSets as
a way to communicate to the Persistence or Data Access Layer. However,
the UI never sees the Typed DataSet. Instead we built custom business
objects that wrap the entity represented by a row in the typed dataset.
Your database is not always going to be an accurate representation of
your business models. So the business object provides an excellent
opportunity to abstract that complexity away from the UI. Additionally,
instead of returning properties that are foreign keys, I can now
implement logic that goes out and get's an another business object based
upon the foreign key (This has drastically reduced the code in our code
behind classes). As for collections, we have a custom collection base
class that wraps a dataview that 'views' a collection of these typed
datarows. When someone enumerates the collection they get the custom
business objects rather than a lifeless snapshot of the database. This
has seriously reduced code replication. I am a true believer in the "If
you can make the program smaller, do it" philosophy. Our first version
of the product passed typed datasets to the client, and we continually
performed the same tasks over and over. The typed dataset is an
unbelievable tool, but IMHO it shouldn't be passed to the UI unless your
application is small, and it's going to change very little. A huge
benefit with our approach, is that I can serialize the entire object
graph simply by Serializing my Typed DataSets. And if designed
properly, I can easily Deserialize by passing the TDS into a constructor
(This is the key to storing the object in session). Also, when it's
time to persist the changes, I can pass the TDS to the Persitence Layer,
and it can find out what the client of the business object did to it by
calling GetChanges on the TDS. I guess if you wanted to use OPENXML to
update the database, you could pass the TDS's xml down to SQL Server. =20

One more note, we don't use the data adapter anywhere in our code.
Instead we use the Microsoft ApplicationBlocks. The Data Application
blocks have been an unbelievably valuable tool in our projects, and best
of all you can get the source code. We haven't modified it yet, but I
have identified some areas that could be made to perform better with the
design I described above.

HTH,
Chris
-----Original Message-----
From: Francesco Sanfilippo [mailto:Click here to reveal e-mail address]=20
Sent: Friday, June 21, 2002 6:31 PM
To: aspngarchitecture
Subject: [aspngarchitecture] Re: Is this good object design???

So you think my initial idea (which was the original post in this
thread) of=20
using a DataTable or DataSet, which would be a property of a Person
object,=20
as a temp cache of user-specific data is sound?

I really want to store these Person objects in Session, to minimize DB=20
traffic as much as possible. I have 4GB of RAM to burn, and want to
speed=20
up performance as much as possible. The DB trip always seems to be the=20
biggest bottleneck.

FS

[Original message clipped]

_________________________________________________________________
Get your FREE download of MSN Explorer at
http://explorer.msn.com/intl.asp.

| [aspngarchitecture] member Click here to reveal e-mail address =3D YOUR ID
| http://www.asplists.com/asplists/aspngarchitecture.asp =3D JOIN/QUIT
| http://www.asplists.com/search =3D SEARCH Archives

Reply to this message...
 
    
Dan Green (VIP)
Francesco,

[Original message clipped]

It's easy enough to do the numbers for your scalability:
# of users * avg dataset size = RAM required

It might be a little tricky to determine avg dataset size, due to the
additional overhead of all the ADO.NET objects involved (not just the
data), but I'm sure you'll be able to manage a reasonable approximation.

The additional concern with using a StateServer, which I haven't seen
mentioned in this thread, is Reliability. If your state hosting machine
goes down, so does your web site, period. This is true regardless of
how many web servers are in the farm. All of them will be
non-responsive.

StateServer is a single point of failure proposition. If that's
acceptable, than you just need to do the scalability numbers. If it's
not, you're going to need to look to using SQLServer as the state
management option. For some bizarro-reason, though, the default
SQLServer scripts use temporary tables. This means it won't be any more
reliable than using StateServer. Weird, eh? But there are two options
to improve on that: (1) Cluster the SQLServer box (I understand this
works with temp tables) (2) change the SQLServer setup scripts to use
non-temp tables. Of course, then performance drops. But we all know by
now that increasing scalability, availability and security means
scarifying performance. Such is our lot. :)

Dan Green
[ http://dotnetdan.com -- putting the dan in .net ]

Reply to this message...
 
    
Deyan Petrov
Hi Matias and all ;),

1) No, definitely not. I will NOT load the whole graph when 1 object is
retrieved. I will load dynamically all the child collections. I will load
all the persons fields in one go, maybe because it will be more efficient
and will not produce a heavy traffic (3 or 10 properties it doesn't make a
big difference for the DB or the network)
2) I cannot quite understand your XML and don't have time to inspect it
carefully, but my idea with the XML serialization is the following - an
object has properties, if a property is changed then the object is modified
and is sent with all of its properties to the DB, as well as with other
modified objects in the collection. The sproc updates all the modified
properties of an object. If an object is new, then it is serialized and sent
with all of its properties to the DB ... If an object is deleted, the only
it's ID is sent to the DB.

As for the other points in the discussion, regarding DataSets - unless you
have a very small project, I wouldn't advise anyone basing there middle tier
on them, even being Typed ... First you cannot hide all the ugly properties
of a Strongly Typed Dataset, inherited from Dataset, hence you can't have
clean domain classes. Second, the DataSet is only a dumb data structure, not
a living business object. It will always restrict you or force you to accept
some of its features. Third, look at the solutions in the Java world, pls,
and wake up. Java arhitects and developers are far ahead of MS VB developers
in my opinion, because the object oriented Java language and J2EE force them
to use design patterns etc. So usually the approach is to build a set of
pure domain classes, after that to abstract the access to them using
facades, persistent managers etc. So you have to keep you business objects
clean and pure, so that you can model the business processes, unaffected by
some data objects and simple containers, what in fact the DataSets are.
That's it, you can say, the strongly typed Dataset is all right with me, I
can use a lot of his features without having to write them myself. But don't
forget about the restrictions it imposes to you, to your program design etc.
Because this is the most important stuff, indeed.
First I started using Data centric approach, having inspected the Duwamish
example. It started quickly to suck. It imposed a stupid procedural design,
when you pass DataSets to methods business objects with manipulate on them.
It is as if you have ALL your methods of your business objects STATIC. Look
at the Duwamish example, pls and ask yourself why you see everywhere sth
like (new BusinessObject()).Method1(myDataSet) haha. The sucking old
stateless (COM+) object approach, no OOP, no polymorphism, nothing...
After that I tried the strongly typed datasets with all their problems of
losing changes after regeneration etc, difficult constructing of XSD schemas
(strange behaivour of relationships in some cases) etc. I read an article,
which benchmarked the speed of creating custom business object collections
and using strongly typed Datasets, the first being faster(sorry, don't have
the link now, but a search in the groups.google.com might help). I didn't
care about it a lot then, but after some time, I got REALLY pissed off by
this data-centric approach, longing for OOP.

Waiting for someone to tell me I am wrong ...

Regards,
Deyan Petrov

----- Original Message -----
From: "Matias Woloski" <Click here to reveal e-mail address>
To: "aspngarchitecture" <Click here to reveal e-mail address>
Sent: Friday, June 21, 2002 8:52 PM
Subject: [aspngarchitecture] RE: Is this good object design???

[Original message clipped]

Reply to this message...
 
    
Brian Espey
Deyan,

i see where you're coming from, but i'm not so sure
the duwamish approach is as horrible as you think.
essentially, it uses datasets purely as value objects
to pass between the different layers of the
application. to me it doesn't seem too terribly
different from the common j2ee patterns (value object,
session facade, data access object, even dependent
objects with entity beans). i suppose the exhaustive
use of static methods does preclude the benefits of
polymorphism, but object-oriented designs and
stateless programming aren't mutually exclusive. you
could just use singletons instead of static methods
for example, and then still get the benefits of
polymorphism and use whatever cool design patterns you
want. your state just becomes an external entity,
whether that is a dataset or a plain old java bean.
it's state that all of your application layers need
access to, so why not externalize it, and make it a
serializable object that you can freely pass around,
using remoting, web services, or whatever?

Brian

--- Deyan Petrov <