Home
Help
Register
Log in

Search

 
   Active Threads  

You are here: Home > LLBLGen Pro > LLBLGen Pro Runtime Framework> Binding problem
 

Pages: 1 2
LLBLGen Pro Runtime Framework
Binding problem
Page:2/2 

  Print all messages in this thread  
Poster Message
daelmo
Support Team



Location:
Guatemala City
Joined on:
28-Nov-2005 23:35:24
Posted:
8148 posts
# Posted on: 18-Mar-2007 01:39:44.  
I'm glad you finally find a workaround for the issue. Wink
Quote:
As an aside, is there an alternative way to get the Type object for System.ComponentModel.Component?

As there are other alternatives, I think that one is good.
David Elizondo
LLBLGen'ing (articles and code snippets) | linkedin | twitter
 
Top
simmotech
User



Location:

Joined on:
01-Feb-2006 15:43:00
Posted:
1010 posts
# Posted on: 09-Jan-2013 17:30:41.  
Well guess who has just come across the same problem...Confused
I'm using DevExpress Grids/Controls but the top of the stack traces are the same.

I spent hours hacking about with BindingContexts before I found this thread.

Now, although Microsoft made a mistake with caching the property descriptors etc., I can't help but think it is exacerbated by the Entity implementation of Equals just comparing IDs.

What was the reasoning for implementing it this way?
What would break if I changed it?
How does ObjectID and/or ActiveContext get used?

I am think along the lines of overriding Equals to only match on Reference Equality or to use ObjectID since, in my case, I am cloning the entity from the collection (and then showing it in a popup form), and I will have the opportunity to change the ObjectID


  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38081 posts
# Posted on: 09-Jan-2013 17:56:55.  
simmotech wrote:
Well guess who has just come across the same problem...Confused
I'm using DevExpress Grids/Controls but the top of the stack traces are the same.

I spent hours hacking about with BindingContexts before I found this thread.

Now, although Microsoft made a mistake with caching the property descriptors etc., I can't help but think it is exacerbated by the Entity implementation of Equals just comparing IDs.

What was the reasoning for implementing it this way?

Equality of entity instances is really about whether their uniquely identifying attributes (PKs) are equal. Entity instances == the data, not the container (object). This thus means that ID field values are compared. If they're equal, the entity instances are equal. There's no other way, as the entity instances represent the same entity in the DB (the PK values are equal).

Quote:

What would break if I changed it?

I don't know how you could change it and still get the same equality functionality.

Quote:

How does ObjectID and/or ActiveContext get used?

ObjectID is the ID of the container, the object, in which the entity instance is stored in. you can store multiple instances of the same entity in multiple containers (so they'll have different objectid's) but the actual entity is the same, e.g. Customer with ID 10.

The context is for uniquing, which means that if you load 2 or more times the same entity instance (e.g. customer with ID 10), without the context you'll get 2 or more different entity class instances (container), with the same data. The context makes it possible to get back the same container for the entity instance, so you re-use the same entity class object, so there's just 1 entity class object (container) loaded for that context.

Quote:

I am think along the lines of overriding Equals to only match on Reference Equality or to use ObjectID since, in my case, I am cloning the entity from the collection (and then showing it in a popup form), and I will have the opportunity to change the ObjectID

You confuse entity class instance with entity instance. These are not the same, see above. To facilitate 'cancel' after entity edits in your situation, you could also use the SaveFields feature and rollback the fields saved if the user presses cancel at the popup screen. No cloning needed.
Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
simmotech
User



Location:

Joined on:
01-Feb-2006 15:43:00
Posted:
1010 posts
# Posted on: 10-Jan-2013 12:55:33.  
It is a matter of interpretation I suppose.

"The definition of what constitutes an object's value is up to the implementer of the type" - MSDN

If I have entity instances A and B and both have the same PK value but one has a particular field set as "A" and one set as "B" then although A.Equals(B) is true, they are not equal in the sense that I could arbitrarily choose one or the other and save it to the database.

But I have thought about this and think your way is the only practical way - comparing all the fields is overkill really.

I was a bit concerned about an XML comment which said that the entities override Equals() but did not override GetHashCode() but this seems not to be the case and GetHashCode does actually match Equals().

Anyway, the net result that no matter how I create a duplicate entity (loading independently from the database or cloning) then as soon as I use any form of binding on it, then the grid that is bound to its 'counterpart' gets a ListChanged event and buggers up all my careful value caching! Crazy but true and that is down to Microsoft's binding and property descriptors.

Whilst saving and rolling back fields might work in some circumstances, it won't work easily here. My app has many workitems which are all independent of one another within a shell form (imagine each displayed in a different tab).
If I have two bank accounts tasks, each showing their transactions in their own grid and I now edit a transaction which is transferring money between them and change the Amount field and save. The source Bank Account Task doesn't (and shouldn't) know whether there is a Task showing the destination Bank Account - all it can do is broadcast a global event with details about the entity that has changed and it is up to the listener method within the task to decide whether the information is pertinent to it and take the appropriate action if it is.
Of course several listening tasks might want to deal with the entity in the global event and so they can either use the ID and reload from the database or clone the item and use it directly. I think this is better than using the original entity from the grid on the edit form since changing the fields will be seen in the source grid but not in any other relevant View and also it may have child entities which are not as easy to revert. Much better to clone the entity and throw it away if the change become unwanted.


  Top
Otis
LLBLGen Pro Team



Location:
The Hague, The Netherlands
Joined on:
17-Aug-2003 18:00:36
Posted:
38081 posts
# Posted on: 10-Jan-2013 17:16:41.  
simmotech wrote:
It is a matter of interpretation I suppose.

"The definition of what constitutes an object's value is up to the implementer of the type" - MSDN

If I have entity instances A and B and both have the same PK value but one has a particular field set as "A" and one set as "B" then although A.Equals(B) is true, they are not equal in the sense that I could arbitrarily choose one or the other and save it to the database.

But I have thought about this and think your way is the only practical way - comparing all the fields is overkill really.

Your example really is what happens in concurrency problem situations: user A has altered customer row C and user B did that too. Who wins? Regular Smiley The in-memory entity instances are really in-memory mirrors of the real instance, which is in the central storage (if you're having a 100-node DB cluster, then that still files for the central storage).

Using the PK value as ID, you can alter the in-memory mirror, and persist the changes as 'changes to be made' on the real instance to the DB. The ID dictates which real instance is altered. So you can have 100 in-memory mirrors of the same entity instance (e.g. customer with ID 10), all have different fields altered, but the same PK value (as it's the same entity instance), they're really representations of changes to be performed on the real instance, which is in the DB.

Quote:

I was a bit concerned about an XML comment which said that the entities override Equals() but did not override GetHashCode() but this seems not to be the case and GetHashCode does actually match Equals().

Hmm. Where exactly?

Quote:

Anyway, the net result that no matter how I create a duplicate entity (loading independently from the database or cloning) then as soon as I use any form of binding on it, then the grid that is bound to its 'counterpart' gets a ListChanged event and buggers up all my careful value caching! Crazy but true and that is down to Microsoft's binding and property descriptors.

Whilst saving and rolling back fields might work in some circumstances, it won't work easily here. My app has many workitems which are all independent of one another within a shell form (imagine each displayed in a different tab).
If I have two bank accounts tasks, each showing their transactions in their own grid and I now edit a transaction which is transferring money between them and change the Amount field and save. The source Bank Account Task doesn't (and shouldn't) know whether there is a Task showing the destination Bank Account - all it can do is broadcast a global event with details about the entity that has changed and it is up to the listener method within the task to decide whether the information is pertinent to it and take the appropriate action if it is.
Of course several listening tasks might want to deal with the entity in the global event and so they can either use the ID and reload from the database or clone the item and use it directly. I think this is better than using the original entity from the grid on the edit form since changing the fields will be seen in the source grid but not in any other relevant View and also it may have child entities which are not as easy to revert. Much better to clone the entity and throw it away if the change become unwanted.

Clone will let you work on the same entity instance in a different entity class instance indeed, as if you've fetched it twice.

Don't overthink it though. Only keep data in-memory in edit forms which has to be saved in the same transaction. If you won't use the same transaction on changes on the entities anyway (read: it's not necessary to do so), don't keep them in-memory unnecessary, just persist the changes when you can, so it gets less complicated.
Frans Bouma
LLBLGen Pro / ORM Profiler Lead Developer | Blog | Twitter
 
Top
simmotech
User



Location:

Joined on:
01-Feb-2006 15:43:00
Posted:
1010 posts
# Posted on: 11-Jan-2013 13:46:27.  
Ignore what I said about the Xml comment. Brain fart on my part. Tongue

The message that appeared at the bottom of the Xml comment was
"'....Entity' overrides Object.Equals(object o) but does not override Object.GetHashcode()"

It was a Resharper warning that it had appended to your Xml Comment in a tooltip and I mistook it as being part of the Xml Comment.

Cheers
Simon


  Top
Pages: 1 2  


Powered by HnD ©2002-2007 Solutions Design
HnD uses LLBLGen Pro

Version: 2.1.12172008 Final.