Objects new in Collection

A

aa7im

I have a similiar thread going about this topic but I decided to break
it off into a seperate discussion.

Question:
What is the best way to determine if an object "IsNew" to a collection?


Problem:
In my application I load a collection of objects from the database and
then pass that collection to the user.

Order.OrderRows // Returns a collection of OrderRows from DB.


If a user does something like: Order.OrderRows.Add(newRow) what is the
best way to determine which rows have been added? I need to this so
that I know whether to persist the relation to the database...

Does my collection need to internally maintain lists of "Added" and
"Deleted" objects so that I can then request a "Changed" list from the
collection like:

Order.OrderRows.GetAdded();
Order.OrderRows.GetDeleted();

===================================================

Or would it be better to wrap all objects in the collection in some
sort of "Item Wrapper" like:

CollectionItem item = new CollectionItem();
item.Value = OrderRow;
item.Status = ItemStatus.Deleted;

So that collection internally would always internally be storing a
collection a CollectionItems (Ok I need better names ;-) ).

So an Add() method on the strongly-typed collection would look like:
public void Add(OrderRow row)
{
List.Add(new CollectionItem(row,item.Status.Added);
}

and to get at items in the collection would look like:
public OrderRow this[int index]
{
get
{
return (OrderRow)((CollectionItem)List[index]).Value;
}
}


Methods like Contains and IndexOf get kind of weird though because then
I have to manually loop through the collection like:

public int IndexOf(OrderRow row)
{
for(int i = 0; i < List.Count; i++)
{
if(List.Value.Equals(row))
{
return i;
}
}
}





Any other ideas? Or am I going about this all wrong?
 
P

Peter Rilling

Most likly you would need to handle that. Create your own custom collection
that has the necessary logic.
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,


Question:
What is the best way to determine if an object "IsNew" to a collection?

Depend of what you mean with that, if you check by actual instances all you
have to do is compare all the elements of the collection with the one you
will insert, with this you will find if two variables reference to the same
instance.

If you want mean value, then you could overload the == operator , or you
could do the comparision in a method of the collection.
Problem:
In my application I load a collection of objects from the database and
then pass that collection to the user.

Order.OrderRows // Returns a collection of OrderRows from DB.


If a user does something like: Order.OrderRows.Add(newRow) what is the
best way to determine which rows have been added? I need to this so
that I know whether to persist the relation to the database...

If OrderRow has a primary key ( not the foreign key to the order number) you
could determine which rows are not persisted to the DB,. just use a default
value , like -1
Does my collection need to internally maintain lists of "Added" and
"Deleted" objects so that I can then request a "Changed" list from the
collection like:

IMO it's better to persist the changes right away, as soon as a row is
delete you delete it from the DB, and a similar thing to the added rows.
doing so will remove the problem you have now.

Cheers,
 
A

aa7im

Unfortuanely I can not persist changes immediately to the DB becuase
everything must be performed within a transaction as one "unit of
work". This allows users to Cancel the action...

I wasn't clear on what I need for the "IsNew" portion of the
collection. I do not need to know whether the object "IsNew" in the
sense that it has never been persisted to the DB (that is simple as you
mention) but that it is "New" to the collection since I loaded it. For
example lets say you loaded an existing object from the database and
want to relate it to another object in a many-to-many relationship.
Hmm... Let me think of an example....

Ok... Lets say that in the Order system there is a list of predefined
"Comments". Multiple comments can be assigned per order such as "30
Day return policy", "Thank you for shopping with us", "Check our sales
flyer coming out next month".... These prexisting comments would be
added like:

Comment firstComment = new Comment(1); Loads comment from DB with ID of
1
Comment secondComment = new Comment(5); Loads comment from DB with ID
of 5
Comment thirdComment = new Comment(7); Loads comment from DB with ID of
7

Order.Comments.Add(firstComment);
Order.Comments.Add(secondComment);
Order.Comments.Add(thirdComment);


Now in the Save() method of the Order object I will need to loop
through the Order.Comments collection and find all the "Comment"
objects that have been added to the order so that I can create the
"relation" records in the DB. Working on existing Order the
Order.Comments collection would already be populated and the collection
after modifications could have a series of "Already Existing
Relations", "Comments that need to have their relations removed", and
"Comments that need a related added".
Any ideas on how to deal with this? THANKS!
 
M

Molybedenum

It looks like you'll have to inherit from the collection or something,
and keep a separate collection / hash that stores the DateTime that
the object was added.

Another nice way to handle it would be to just use a Hashtable. When
you add an object to the Hashtable, use the DateTime it was added as
the key. You can play around with this however you want, using an
iterator for the keys, or iterating the object directly.

You might want to create a class that encapsulates whatever
information that you're storing too, so that you can keep metadata
about that information available. This could also include date/time
information. You wouldn't need a Hashtable for this method. You
could use an ArrayList, and just implement the IComparable interface,
or create an IComparer for sorting of that list.

There are quite a few ways to go about it.

*-----------------------*
Posted at:
www.GroupSrv.com
*-----------------------*
 
F

Frans Bouma [C# MVP]

Ignacio said:
IMO it's better to persist the changes right away, as soon as a row is
delete you delete it from the DB, and a similar thing to the added rows.
doing so will remove the problem you have now.

Removing an object from a collection doesn't have to mean removing it
from the db. Removing an entity object from an entity collection in
memory can mean 3 things: (example: myOrder is removed from
myCustomer.Orders)

1) the relation between myCustomer and myOrder is removed
2) myOrder is / has to be removed from the db
3) myOrder is not needed in the Orders collection for this moment as
Orders contains just a snapshot of all the orders of myCustomer, and
myOrder is not in that snapshot.

Which one to follow when Orders.Remove(myOrder) is called? I don't
know. Also, what if the user later on clicks 'cancel' and the remove has
to be rolled back? You instantly have to undelete the deleted object!
But you can't roll back a db transaction at that point because one of
the basic rules of transactions is: "Do not allow user interaction when
the transaction runs".

Frans.
 
F

Frans Bouma [C# MVP]

aa7im said:
I have a similiar thread going about this topic but I decided to break
it off into a seperate discussion.

Question:
What is the best way to determine if an object "IsNew" to a collection?

why do you care? :) The entities are important, not the collection,
that's just a container with objects which apparently obey a certain
filter (Order.CustomerID = 1 for example, which are located in
myCustomer.Orders, myCustomer contains the data of customer with ID =1).

Frans.
 
A

aa7im

This would work in cases where there is a 1:1 or 1:Many relationships
between entites but breaks down in Many:Many relation ships becuase
there is no FK field on the entity. This means I have to know which
items have been added to a collection for Many:Many relations so I can
create the seperate entry in the table that ties the 2 entities
together. Unless there is another way to do it...


tblInvoice
+ InvoiceID: int PK
+ OrderDate: datetime

tblComments
+ CommentID: int PK
+ Title: string

tblInvoiceComments
+ InvoiceCommentID: int PK
+ InvoiceID: int
+ CommentID: int
 
A

aa7im

This would work in cases where there is a 1:1 or 1:Many relationships
between entites but breaks down in Many:Many relation ships becuase
there is no FK field on the entity. This means I have to know which
items have been added to a collection for Many:Many relations so I can
create the seperate entry in the table that ties the 2 entities
together. Unless there is another way to do it...


tblInvoice
+ InvoiceID: int PK
+ OrderDate: datetime

tblComments
+ CommentID: int PK
+ Title: string

tblInvoiceComments
+ InvoiceCommentID: int PK
+ InvoiceID: int
+ CommentID: int
 
A

aa7im

This would work in cases where there is a 1:1 or 1:Many relationships
between entites but breaks down in Many:Many relation ships becuase
there is no FK field on the entity. This means I have to know which
items have been added to a collection for Many:Many relations so I can
create the seperate entry in the table that ties the 2 entities
together. Unless there is another way to do it...


tblInvoice
+ InvoiceID: int PK
+ OrderDate: datetime

tblComments
+ CommentID: int PK
+ Title: string

tblInvoiceComments
+ InvoiceCommentID: int PK
+ InvoiceID: int
+ CommentID: int
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top