473,748 Members | 2,672 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Best practice keeping business object collection synced to DB

I'm testing the waters of n-tier development and I ran into a scenario that
I'm not sure what the best solution would be. I have a Company object which
contains a collection of contacts retrieved from a database.

In the presentation layer, the user will be able to add/delete/modify this
collection in which case it needs to be synced with the database.

The question is basically how best to do this? Aside from overriding the
add/remove methods of the collection, I can't think of any way to maintain a
1:1 correspondence between what's in the collection and what's in the DB.

I would do this, but something tells me it's not a good idea to have the
collection know about database access.

Or am I asking too much to have the collection synced? Should I just
provide methods on the Company object which let me add/delete/edit a
contact? Which means if a developer modifies the collection directly, it
won't occur in the DB.

Thanks,
-A
Nov 17 '05 #1
9 5490
"Alfred Taylor" <om***@R-E-M-O-V-Eyahoo.com> wrote in message
news:e9******** ******@TK2MSFTN GP09.phx.gbl...
I'm testing the waters of n-tier development and I ran into a scenario
that I'm not sure what the best solution would be. I have a Company
object which contains a collection of contacts retrieved from a database.

In the presentation layer, the user will be able to add/delete/modify this
collection in which case it needs to be synced with the database.

The question is basically how best to do this? Aside from overriding the
add/remove methods of the collection, I can't think of any way to maintain
a 1:1 correspondence between what's in the collection and what's in the
DB.


Why not simply replace your collection with a strongly typed dataset? That
still allows you independance from the data source, while at the same time
allowing you to pass a dataset back to a data layer (DataSet.GetCha nges())
for much easier updates.

What is a collection, really? It's just a list of items, each one with
properties like LastName, PhoneNumber, etc. A strongly typed dataset gives
you the exact same thing, but with built in ways to update the data source.

HTH,

Mike Rodriguez
Nov 17 '05 #2
Hrmm. That's an interesting suggestion. I just spent the past hour or so
reading MSDN articles and it seems like using a DataSet would greatly
simplify a lot of things.

I'll take a closer look at it tomorrow when I have more time. Thanks for
the suggestion.

Anybody else have any input?

-A

"Michael Rodriguez" <mi**@nospamfor me.com> wrote in message
news:e3******** ******@TK2MSFTN GP10.phx.gbl...
"Alfred Taylor" <om***@R-E-M-O-V-Eyahoo.com> wrote in message
news:e9******** ******@TK2MSFTN GP09.phx.gbl...
I'm testing the waters of n-tier development and I ran into a scenario
that I'm not sure what the best solution would be. I have a Company
object which contains a collection of contacts retrieved from a database.
In the presentation layer, the user will be able to add/delete/modify this collection in which case it needs to be synced with the database.

The question is basically how best to do this? Aside from overriding the add/remove methods of the collection, I can't think of any way to maintain a 1:1 correspondence between what's in the collection and what's in the
DB.

Why not simply replace your collection with a strongly typed dataset?

That still allows you independance from the data source, while at the same time
allowing you to pass a dataset back to a data layer (DataSet.GetCha nges())
for much easier updates.

What is a collection, really? It's just a list of items, each one with
properties like LastName, PhoneNumber, etc. A strongly typed dataset gives you the exact same thing, but with built in ways to update the data source.
HTH,

Mike Rodriguez

Nov 17 '05 #3
Alfred Taylor wrote:
I'm testing the waters of n-tier development and I ran into a
scenario that I'm not sure what the best solution would be. I have a
Company object which contains a collection of contacts retrieved from
a database.

In the presentation layer, the user will be able to add/delete/modify
this collection in which case it needs to be synced with the database.

The question is basically how best to do this? Aside from overriding
the add/remove methods of the collection, I can't think of any way to
maintain a 1:1 correspondence between what's in the collection and
what's in the DB.

I would do this, but something tells me it's not a good idea to have
the collection know about database access.

Or am I asking too much to have the collection synced? Should I just
provide methods on the Company object which let me add/delete/edit a
contact? Which means if a developer modifies the collection
directly, it won't occur in the DB.


Keeping a disconnected datastore, be it a dataset or collection of
objects, in sync with the DB is always a challenge. THere are two
different scenario's.

1) simply remove the state for the data in the db and replace it with
the current state in the object collection
or
2) track changes made to the object collection, and replay them on the
datastore.

Another person suggested a typed dataset, but that's not going to help
you, you still have to sort the changes out, create sql to get things
done.

take for example the removal of a contact from a company's contacts
list. Is that just the removal of the contact from the list (i.e. an
in-memory action, not affecting any data in the db)?, or is that equal
to: delete the contact? or is that equal to: reset the FK in contact to
company?

A dataset won't solve that for you, you have to write code like that
yourself, always, it then comes down to: what's the easiest way out?

Most of the time, you go for option 1: first perform a delete from
contacts where companyid = @companyID and then perform inserts for the
contacts still in company.Contact s. Then you perform a refetch of the
contacts to read default constraint values and calculated column values.

It can be that's not feasable for your situation so you have to track
the changes made to the collection in memory and replay them one by one
onto the db. A typical object to do taht with is a UnitOfWork, using
the Unit of work pattern, almost every O/R mapper has one.

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------
Nov 17 '05 #4

"Frans Bouma [C# MVP]" <pe************ ******@xs4all.n l> wrote in message
news:xn******** *******@news.mi crosoft.com...

Keeping a disconnected datastore, be it a dataset or collection of
objects, in sync with the DB is always a challenge. THere are two
different scenario's.
Tell me about it. ;)

1) simply remove the state for the data in the db and replace it with
the current state in the object collection
or
2) track changes made to the object collection, and replay them on the
datastore.
Those are the _exact_ problems that led me to make this post. I'm glad I'm
not the only one feeling lost here.

Another person suggested a typed dataset, but that's not going to help
you, you still have to sort the changes out, create sql to get things
done.
I'm completely new to DataSets, but correct me if I'm wrong in saying the
DataSet will keep track of those changes for me. I believe it's the
RowState property that will let me know if the row has been updated,
deleted, etc. I also did a quick example and it looks like the
update/delete/insert statements can be automatically generated for me if I
want. All I have to do is specify the initial SELECT statement.

It seems like the DataSet will solve a lot of problems (and reduce code).
I'm just not going to get a 1:1 correspondence which I'm beginning to be
okay with. Like I said, I'm not an expert on DataSets but it seems like all
the problems you're describing can be solved using a DataSet.

Thanks,
-A

take for example the removal of a contact from a company's contacts
list. Is that just the removal of the contact from the list (i.e. an
in-memory action, not affecting any data in the db)?, or is that equal
to: delete the contact? or is that equal to: reset the FK in contact to
company?

A dataset won't solve that for you, you have to write code like that
yourself, always, it then comes down to: what's the easiest way out?

Most of the time, you go for option 1: first perform a delete from
contacts where companyid = @companyID and then perform inserts for the
contacts still in company.Contact s. Then you perform a refetch of the
contacts to read default constraint values and calculated column values.

It can be that's not feasable for your situation so you have to track
the changes made to the collection in memory and replay them one by one
onto the db. A typical object to do taht with is a UnitOfWork, using
the Unit of work pattern, almost every O/R mapper has one.

Frans

--
------------------------------------------------------------------------
Get LLBLGen Pro, productive O/R mapping for .NET: http://www.llblgen.com
My .NET blog: http://weblogs.asp.net/fbouma
Microsoft MVP (C#)
------------------------------------------------------------------------

Nov 17 '05 #5
"Frans Bouma [C# MVP]" <pe************ ******@xs4all.n l> wrote in message
news:xn******** *******@news.mi crosoft.com...
Alfred Taylor wrote:

Another person suggested a typed dataset, but that's not going to help
you, you still have to sort the changes out, create sql to get things
done.


It's true that you still have to create sql statements to get things done.
That is going to be the case no matter what approach you take. The
advantages of a dataset are:

- Better built-in support data binding
- Built-in abilities to keep track of which rows have been modified,
deleted, etc.
- The biggest benefit, as far as code reduction, being able to use a
DataAdapter. With the data adapter, all you have to do is define the
insert, update and delete statements. Then, just give it your dataset and
VS will call the appropriate sql statements for each row. That is a major
code saver. A colleague of mine had a data layer based on a collection. He
had to write code to figure out when and where to call which sql statements.
I showed him my approach with the data adapter and it cut his code size to
1/4 of what it had been before.

Some notes about using a data adapter. The select statement is pretty
self-explanatory. For the insert, update and delete statements, I would
modify the ones VS generates. For the insert statement, immediately after
doing the insert, reselect the record like so:

INSERT INTO customers(id, name) ; SELECT id, name FROM customers WHERE id =
@@IDENTITY -- sql server specific

This allows you to get the values of any autoincrement fields, default
values, etc. that sql changed and that your UI will need to know about. Do
the same thing for the update statement. Also, in my update statements, I
only select the record based on the primary key and a timestamp field. That
way you will know if another user has changed the data since you queried it.
Again, the nice thing about the dataset/dataadapter approach is VS will
throw the concurrency error for you automatically in this case (0 rows
affected = concurrency error). For the delete statement, I only delete
based on the primary key.

Using this approach I have been able to generate a data layer is very
minimal. Also, get a code generator! I use My Generation. Let it generate
your entire data layer for you, saving you hours of repetitive work.

HTH,

Mike Rodriguez
Nov 17 '05 #6
Hi Michael,

Thanks for your posts. They've been extremely helpful and have opened my
eyes to a whole new world. ;)

Initially I guess I wasn't even going to have the data layer and have my
business object get data from the DB directly. Now that I have a data layer
(a DataSet with all my data), I'm having problems exposing it in the
business logic.

For example, I can have business object called Company which has properties
that will expose the fields of a DataRow. That's fine and seems like the
right thing to be doing.

But I also have the now famous Contacts collection which I talked about in
the initial post. With this new model, my Contacts collection is now a
DataTable with rows of Contacts. How would I go about exposing this in the
Company object?

I don't want to have a property on the Comany that returns the DataTable as
that seems to violate OOP. People who use the Company object shouldn't know
the underlying datastore . . .

I thought about creating a new collection which uses the datatable as
storage and exposes the DataTable methods that I need, but this doesn't
"sit" right with me.

So I'm kind of at a loss. Any suggestions?

Thanks,
-A
Nov 17 '05 #7
"Alfred Taylor" <om***@R-E-M-O-V-Eyahoo.com> wrote in message
news:eK******** ******@TK2MSFTN GP12.phx.gbl...
Hi Michael,

Thanks for your posts. They've been extremely helpful and have opened my
eyes to a whole new world. ;)

Initially I guess I wasn't even going to have the data layer and have my
business object get data from the DB directly. Now that I have a data
layer (a DataSet with all my data), I'm having problems exposing it in the
business logic.

For example, I can have business object called Company which has
properties that will expose the fields of a DataRow. That's fine and
seems like the right thing to be doing.

But I also have the now famous Contacts collection which I talked about in
the initial post. With this new model, my Contacts collection is now a
DataTable with rows of Contacts. How would I go about exposing this in
the Company object?


Hi Alfred,

Personally, I wouldn't have any custom defined business data objects. All
of my business data objects are strongly typed datasets. I use those
datasets in my business classes to expose all of the functionality I need
(Get, Update, Validate, etc). It seems like you're looking to link your
Company object with your Contacts object. Is this because of a
master-detail relationship? If so, datasets have built-in ways to manage
this as well. When you move to a new record in the master the detail
records change automatically. Also, you can write a C# program to build all
of your dataset classes for you based on your existing schema. If you'd, I
could email you a sample of that.

You can try to write your own data objects that have better functionality
for handling data than the ADO.NET DataSet, but I decided a long time ago
that Microsoft was better than me on this one. Why not take advantage of
their hard work?

HTH,

Mike Rodriguez
Nov 17 '05 #8

"Michael Rodriguez" <mi**@nospamfor me.com> wrote in message
news:eL******** ******@TK2MSFTN GP09.phx.gbl...
Hi Alfred,

Personally, I wouldn't have any custom defined business data objects. All
of my business data objects are strongly typed datasets. I use those
datasets in my business classes to expose all of the functionality I need
(Get, Update, Validate, etc). It seems like you're looking to link your
Company object with your Contacts object. Is this because of a
master-detail relationship? If so, datasets have built-in ways to manage
this as well. When you move to a new record in the master the detail
records change automatically. Also, you can write a C# program to build
all of your dataset classes for you based on your existing schema. If
you'd, I could email you a sample of that.
You know what would _really_ help me out? If you/someone could give me a
snippet of a business object so that I can see how it's interacting
with/exposing the data objects. I conceptualize so much better with
examples. So if you wouldn't mind sending me something like that, I'd
appreciate it.

Thanks,
-A

You can try to write your own data objects that have better functionality
for handling data than the ADO.NET DataSet, but I decided a long time ago
that Microsoft was better than me on this one. Why not take advantage of
their hard work?

HTH,

Mike Rodriguez

Nov 17 '05 #9
In message <xn************ ***@news.micros oft.com>, "Frans Bouma [C#
MVP]" <pe************ ******@xs4all.n l> writes
Most of the time, you go for option 1: first perform a delete from
contacts where companyid = @companyID and then perform inserts for the
contacts still in company.Contact s. Then you perform a refetch of the
contacts to read default constraint values and calculated column values.


I've found the SQLServer XML support useful for doing this kind of thing
with fewer database calls, particularly where the related records
already exist and the operation is to populate a joining table. I've got
a converter which will take any of my standard collections and convert
them to a consistent XML format. Getting the values out and into a
temporary table is then just boilerplate code in the stored procedure.

--
Steve Walker
Nov 17 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
9267
by: DrUg13 | last post by:
In java, this seems so easy. You need a new object Object test = new Object() gives me exactly what I want. could someone please help me understand the different ways to do the same thing in C++. I find my self sometimes, trying Object app = Object(); Object *app = Object(); Object app = new Object();
2
1480
by: Sjaakie Helderhorst | last post by:
Hi, What's the best way of storing a dataset (+/-1000 rows, 9 columns)? I'm using a session-variable but this seems to have serious impact on performance. It's a shop and I'm using the same dataset (added an 'amount' cell) to generate a dataview for basket Most users will use the shop to order at 5pm (about 800 users), so I want to keep server-stress within acceptable parameters. Any help or suggestion is appreciated.
18
2865
by: D Witherspoon | last post by:
I am developing a Windows Forms application in VB.NET that will use .NET remoting to access the data tier classes. A very simple way I have come up with is by creating typed (.xsd) datasets. For example dsParts.xsd and including that in the data tier. I then will create a class that looks like this Public Class CPart Inherits dsParts
6
1637
by: Nate | last post by:
I am in a slight predicament trying to determine the most efficient and effective way to connect/disconnect from a database within a business object (c# dll). I'm also keeping in mind the concept of connecting late and disconnecting early. Background: - multi-tier application (code-behind uses properties and methods of the business object, the business object handles the data layer) For instance (in an ASPX code-behind file):
28
9134
by: Michael Primeaux | last post by:
What is the recommended pattern for implementing a synchronized (thread-safe) class that inherits from Collection<T>? For example, I want to implement a SyncRoot property . I do see where I can override (protected) the methods InsertItem, RemoveItem, ClearItems, and SetItem. However, I do not see an override for GetItem. Kindest regards, Michael
3
1814
by: cbrown | last post by:
I am rebuilding an existing application that relies on an SQL DB. The app is a scheduling/employee management program. My question pertains to best practices in dotnet and database. I use a 3 tier model and have custom classes for things like Employees. What comes to question is when I load an Employee from my DB, I populate the properties of the object with the data in the dataset. When I want to view the employee on a form, i bind...
13
3113
by: Alan Silver | last post by:
Hello, MSDN (amongst other places) is full of helpful advice on ways to do data access, but they all seem geared to wards enterprise applications. Maybe I'm in a minority, but I don't have those sorts of clients. Mine are all small businesses whose sites will never reach those sorts of scales. I deal with businesses whose sites get maybe a few hundred visitors per day (some not even that much) and get no more than ten orders per day....
5
2884
by: Frank Millman | last post by:
Hi all This is not strictly a Python question, but as I am writing in Python, and as I know there are some XML gurus on this list, I hope it is appropriate here. XML-schemas are used to define the structure of an xml document, and to validate that a particular document conforms to the schema. They can also be used to transform the document, by filling in missing attributes with default values.
0
8995
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9561
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9332
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9254
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6799
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6078
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4608
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2217
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.