v2.1 - request for changes....

Posts   
 
    
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 10-Nov-2006 11:04:04   

Hi Frans

I see in other threads that v2.1 is under planning/development.

Could I request the following non-breaking changes to be incorporated - this will help with the serialization article I said I would write specifically for LLBLGenPro.

EntityBase2 (and related) 1) Make ObjectID lazy-initialized - only about half a dozen lines to change As I think we discussed previously, this is not only more efficient anyway since Guid generation is relatively slow, but can be used to determine which entities are (or have been) involved in relations. 2) Define CreateEntityFactory() as "protected internal virtual" instead of just "protected virtual"

EntityCollectionBase2 (and related) 1) Define InitClass() as "internal" rather than "private"

None of these changes would break backwards compatibility but would mean that the code for serialization would be virtually just one block of code added at the bottom of the class.

You're gonna love the latest version - I speeded up the string tokenization by around 10% and, using a slightly tweaked version of the code from this article http://www.codeproject.com/useritems/managedlzo.asp, can get ~91% compression in less than 0.363 seconds (original was ~14MB and took 93+ seconds) - this includes the code to check for referenced entities - without this time is less than 0.25 seconds

Cheers Simon

PS Adding additional Enum constructors ala this thread, http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7131&HighLight=1 was on the todo list - is this likely to make it? and if so, for all objects requiring it?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 11-Nov-2006 12:37:47   

simmotech wrote:

Hi Frans I see in other threads that v2.1 is under planning/development.

It's in early planning phase, so ideas are cooking so to speak simple_smile . (I like to think for a while on ideas before digging in and start designing). The end of the development cycle of our next version of the forum system is close (this forum will migrate to it today), which we will release as open source and an LLBLGen Pro example application next week or so, so time is available very shortly to start full steam ahead simple_smile

Could I request the following non-breaking changes to be incorporated - this will help with the serialization article I said I would write specifically for LLBLGenPro.

EntityBase2 (and related) 1) Make ObjectID lazy-initialized - only about half a dozen lines to change As I think we discussed previously, this is not only more efficient anyway since Guid generation is relatively slow, but can be used to determine which entities are (or have been) involved in relations.

This is a small change so I've added it to the ToDo list. I don't fully grasp the last part of your remark, about the relations part.

2) Define CreateEntityFactory() as "protected internal virtual" instead of just "protected virtual"

I had to lookup what protected internal meant, and first thought that the 'internal' marker would make the method protected in the current assembly but not accessable in another assembly, but it's just making the method also accessable to other classes in the same assembly but not accessable in a derived class in another assembly. OK, this can be done. simple_smile

EntityCollectionBase2 (and related) 1) Define InitClass() as "internal" rather than "private"

This can't be done, unless it's added to an internal interface, otherwise you can't access the method without using generics. The internal interface is there, so you have internal access to methods in a generic collection. You need this routine to pre-init a collection before a deserialization cycle starts?

None of these changes would break backwards compatibility but would mean that the code for serialization would be virtually just one block of code added at the bottom of the class.

I like the sound of that simple_smile

You're gonna love the latest version - I speeded up the string tokenization by around 10% and, using a slightly tweaked version of the code from this article http://www.codeproject.com/useritems/managedlzo.asp, can get ~91% compression in less than 0.363 seconds (original was ~14MB and took 93+ seconds) - this includes the code to check for referenced entities - without this time is less than 0.25 seconds

Just incredible simple_smile .

PS Adding additional Enum constructors ala this thread, http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7131&HighLight=1 was on the todo list - is this likely to make it? and if so, for all objects requiring it?

None of these things is decided for 100%. Your serialization optimizations are a good candidate, so are a few other things, which have high priority, like custom entities.

Changes which take just a few lines of code are not the ones likely to drop off the list, so I'm pretty sure these will make it in, but in general, I can't promise for 100% to avoid dissapointment (I have to say that to all of you, so I won't shoot myself in the foot). The todo list is still long, and a lot of tiny things are on that list and all together take still a lot of time, so in the prioritizing phase some things might fall off, but I've marked your requests as top priority for now as they are very minor and give you an easy way to update the code with a single action (i.e. partial class simple_smile ) and recompile the runtime and have ultrafast serialization.

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 11-Nov-2006 13:02:50   

If you are opening a discussion of desired features for the next version, I've a few. - Aggregates in projections - Virtual table support - Improved Delete semantics on collections. So we can say delete this entity from this collection and when the collection is save also delete it from the database.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 11-Nov-2006 14:02:37   

arschr wrote:

If you are opening a discussion of desired features for the next version, I've a few.

I haven't opened a discussion about this yet, but you can always step forward simple_smile

  • Aggregates in projections

And grouping you mean as well? I'll think about it. First thing that has to be in the projections is related data. It's complex material, so it's unclear if this is doable without writing a full in-memory database engine

  • Virtual table support

you mean 'derived tables' like: select * from a inner join (select ... from b where... ) as bsubset on a.field = bsubset.field

? (so '(select ... from b where... ) as bsubset' is the derived table)

  • Improved Delete semantics on collections. So we can say delete this entity from this collection and when the collection is save also delete it from the database.

It won't be implemented directly on the collection, and I've explained that a couple of times so I won't rehash that here again.

What the datasourcecontrols have shown is that it can be done if the work is delegated to a unitofwork object. So I'm thinking of some sort of attach mechanism in where you can attach a UoW to a collection and deletes and other changes are tracked in the UoW. The main disadvantage of re-implementing it on the collection is simply that it's a rehash of a UoW class but then simpler, so a UoW attached to the collection is useful. So it will require you to have a UoW around or use it in your code, but IMHO that's pretty minor.

As said, nothing is finalized, as currently our big example (this forum as v2.0) is in its final stages (migration later today, sourcecode release after a week or so), so 2.1 dev starts after that.

Frans Bouma | Lead developer LLBLGen Pro
arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 11-Nov-2006 21:09:32   

And grouping you mean as well?

Yes, But you are already doing distinct projections, so aggregates are just a small step away. smile

you mean 'derived tables' like: select * from a inner join (select ... from b where... )

Yes.

It won't be implemented directly on the collection, and I've explained that a couple of times so I won't rehash that here again.

O.k.

simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 12-Nov-2006 11:49:18   

Hi Frans

(I have trouble with the quoting thing so I'll just answer the outstanding questions...)

The 'relations' part just means that if the underlying _objectID field is Guid.Empty then the Entity has not been used in a related entity collection and so there won't be any circular references to worry about.

Setting InitClass to 'internal' rather than 'private' just means that it can be called by another class within ORMSupportClasses - nothing more than that - I don't see where generics comes into it (in fact my code is currently all .NET 1.1 for compatibility although it works fine under .NET 2.0 and is about 10% faster still!). Yes, using surrogates means I have a completely uninitialized collection (no constructors have been called), so rather than duplicate the code (which may change over time), if the method is internal then it is still 'hidden' from code outside the runtime library but the deserializer can call it to setup the class correctly.

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Nov-2006 12:42:52   

simmotech wrote:

Hi Frans

(I have trouble with the quoting thing so I'll just answer the outstanding questions...)

I've fixed this now for IE too, please check if the buttons at the bottom now work for you. There are some small glitches in the UBB parser (which is brand new) so if you ran into a glitch or error please let us know so we can fix this a.s.a.p.

The 'relations' part just means that if the underlying _objectID field is Guid.Empty then the Entity has not been used in a related entity collection and so there won't be any circular references to worry about.

Ah ok simple_smile

Setting InitClass to 'internal' rather than 'private' just means that it can be called by another class within ORMSupportClasses - nothing more than that - I don't see where generics comes into it (in fact my code is currently all .NET 1.1 for compatibility although it works fine under .NET 2.0 and is about 10% faster still!).

In .NET 2.0, EntityCollectionBase2 is a generic class. So you can't do: ((EntityCollectionBase2)coll).InitClass();

you have to cast with a generic parameter, e.g.: ((EntityCollectionBase2<CustomerEntity>)coll).InitClass();

otherwise the cast won't succeed, and there's no other way to access the internal methods, except one: the internal interface I've created for that purpose, so I'll add the method to that interface, as you don't know that generic type.

Yes, using surrogates means I have a completely uninitialized collection (no constructors have been called), so rather than duplicate the code (which may change over time), if the method is internal then it is still 'hidden' from code outside the runtime library but the deserializer can call it to setup the class correctly.

Yes I know the idea wink , I just wanted to know why you want it so I have a rational reason why the method is internal and not private. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 12-Nov-2006 12:44:48   

arschr wrote:

And grouping you mean as well?

Yes, But you are already doing distinct projections, so aggregates are just a small step away. smile

Heh, no I don't think it is unfortunately, but that's ok, it's also not that hard. The distinct problem is solved without grouping, where grouping has to create hash-sets per value per group. Not that big of a deal but the main issue is that it's obsolete within a year when Linq arrives which has this out of the box. simple_smile (but ok, till then you can use it)

Frans Bouma | Lead developer LLBLGen Pro
Posts: 94
Joined: 26-Feb-2006
# Posted on: 19-Nov-2006 23:39:10   

Frans,

besides the completion of Hnd I ´d like to add a request for WCF support for the next release 2.1.. sunglasses

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 20-Nov-2006 08:24:07   

adrianporger wrote:

Frans,

besides the completion of Hnd I ´d like to add a request for WCF support for the next release 2.1.. sunglasses

It should work with v2.0, but perhaps some new interfaces etc. have to be implemented in a special .net 3.0 build, not sure and we'll check it out of course. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 08-Dec-2006 06:55:05   

Hi Otis

Can I retract that ToDo list item for making ObjectID lazy-instantiated?

Most of the reasons I had for suggesting it (mainly serializing 16 bytes per entity when 1 would do) are now gone.

Can you think of any reason why the original entity ObjectID needs to be preserved when serializing a graph? The serialization code I have at the moment doesn't need ObjectID Guids anymore and so I am just creating a new one on deserialization (references between entities still preserved of course - just not via the Guid)

The other question I had was about why ObjectID is not used for the HashCode?

Cheers Simon

PS removal of Guids/alternative method of linking referenced entities make a big difference:

Test : Collection of 139 entities Graph: 467 entities with 279 referenced

Serialization: Optimization.None: 1,132,722 bytes Optimization.Owned: 1,010,272 bytes (10.81% reduction) Optimization.Fast: 17,934 bytes (98.42% reduction)

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Dec-2006 10:39:23   

simmotech wrote:

Hi Otis

Can I retract that ToDo list item for making ObjectID lazy-instantiated?

You can simple_smile THough I think I'll make it lazy loaded anyway, as I want to implement a couple of optimizations based on your ideas as well for the people who won't recompile the dll. simple_smile

Most of the reasons I had for suggesting it (mainly serializing 16 bytes per entity when 1 would do) are now gone.

Can you think of any reason why the original entity ObjectID needs to be preserved when serializing a graph? The serialization code I have at the moment doesn't need ObjectID Guids anymore and so I am just creating a new one on deserialization (references between entities still preserved of course - just not via the Guid)

It's the only identifying element of an entity object in memory. So if a client in a distributed scenario sends an entity object to the server and the server sends the same entity object back in return, the client can identity that object based on the objectid. That's the reason it's serialized. The PK won't do because you can have multiple instances of the same entity in different entity objects.

The other question I had was about why ObjectID is not used for the HashCode?

The PK values are used for the hashcode so Equals results in a similar operation as GetHashCode and they're not working on different values.

PS removal of Guids/alternative method of linking referenced entities make a big difference:

Test : Collection of 139 entities Graph: 467 entities with 279 referenced

Serialization: Optimization.None: 1,132,722 bytes Optimization.Owned: 1,010,272 bytes (10.81% reduction) Optimization.Fast: 17,934 bytes (98.42% reduction)

What exactly do you mean with alternative method of linking referenced entities?

Frans Bouma | Lead developer LLBLGen Pro
simmotech
User
Posts: 1024
Joined: 01-Feb-2006
# Posted on: 08-Dec-2006 12:21:55   

Otis wrote:

simmotech wrote:

Hi Otis

Can I retract that ToDo list item for making ObjectID lazy-instantiated?

You can simple_smile THough I think I'll make it lazy loaded anyway, as I want to implement a couple of optimizations based on your ideas as well for the people who won't recompile the dll. simple_smile

Most of the reasons I had for suggesting it (mainly serializing 16 bytes per entity when 1 would do) are now gone.

Can you think of any reason why the original entity ObjectID needs to be preserved when serializing a graph? The serialization code I have at the moment doesn't need ObjectID Guids anymore and so I am just creating a new one on deserialization (references between entities still preserved of course - just not via the Guid)

It's the only identifying element of an entity object in memory. So if a client in a distributed scenario sends an entity object to the server and the server sends the same entity object back in return, the client can identity that object based on the objectid. That's the reason it's serialized. The PK won't do because you can have multiple instances of the same entity in different entity objects.

PS removal of Guids/alternative method of linking referenced entities make a big difference:

Test : Collection of 139 entities Graph: 467 entities with 279 referenced

Serialization: Optimization.None: 1,132,722 bytes Optimization.Owned: 1,010,272 bytes (10.81% reduction) Optimization.Fast: 17,934 bytes (98.42% reduction)

What exactly do you mean with alternative method of linking referenced entities?

All of the entities in the graph are calculated. Those that are referenced are processed first by writing their owned data only. A second loop then writes their reference information but instead of writing Guids, Ijust write their index in the ReferencedEntities List. Deserialization is the reverse process - all of the referenced entities are created with just their owned data and a second loop puts their references back by looking up the entity in the Referenced Entity list.

The code I have can write the Guid or not - doesn't matter. In the example above, the serialized collection is 20,174 bytes when entity ObjectIDs are saved.

However, I'm a bit confused over expectations for Distributed Scenerio. I thought your position was that a service interface should be used and that a collection retrieved via the interface was to replace any existing collection and any GUI controls be rebound to the new collection. That being the case, wouldn't ObjectIDs become irrelevant?

Cheers Simon

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Dec-2006 12:48:55   

simmotech wrote:

Otis wrote:

PS removal of Guids/alternative method of linking referenced entities make a big difference:

Test : Collection of 139 entities Graph: 467 entities with 279 referenced

Serialization: Optimization.None: 1,132,722 bytes Optimization.Owned: 1,010,272 bytes (10.81% reduction) Optimization.Fast: 17,934 bytes (98.42% reduction)

What exactly do you mean with alternative method of linking referenced entities?

All of the entities in the graph are calculated. Those that are referenced are processed first by writing their owned data only. A second loop then writes their reference information but instead of writing Guids, Ijust write their index in the ReferencedEntities List. Deserialization is the reverse process - all of the referenced entities are created with just their owned data and a second loop puts their references back by looking up the entity in the Referenced Entity list.

The code I have can write the Guid or not - doesn't matter. In the example above, the serialized collection is 20,174 bytes when entity ObjectIDs are saved.

Ah thanks simple_smile

However, I'm a bit confused over expectations for Distributed Scenerio. I thought your position was that a service interface should be used and that a collection retrieved via the interface was to replace any existing collection and any GUI controls be rebound to the new collection. That being the case, wouldn't ObjectIDs become irrelevant? Cheers Simon

Sure, there's a recommended way of doing distributed applications, but sometimes people want to use a different way of distributed applications, e.g. they use a context on the client and simply pull the returned entity again through the context to get the same object back which can be convenient if the object is bound to a control for example.

Frans Bouma | Lead developer LLBLGen Pro
Answer
User
Posts: 363
Joined: 28-Jun-2004
# Posted on: 09-Dec-2006 07:57:46   

Most of the reasons I had for suggesting it (mainly serializing 16 bytes per entity when 1 would do) are now gone.

Can you think of any reason why the original entity ObjectID needs to be preserved when serializing a graph? The serialization code I have at the moment doesn't need ObjectID Guids anymore and so I am just creating a new one on deserialization (references between entities still preserved of course - just not via the Guid)

Please do not get rid of the ObjectID, it comes in quite handy simple_smile

My app is a distributed scenario and it works great for identify which entity is which on the return trip...

However, I'm a bit confused over expectations for Distributed Scenerio. I thought your position was that a service interface should be used and that a collection retrieved via the interface was to replace any existing collection and any GUI controls be rebound to the new collection. That being the case, wouldn't ObjectIDs become irrelevant? Cheers Simon

This is exactly how i do it...However on some of my forms, i need to upload an image along with the entity. So prior to sending the entity graph to the server (where it determines the image files names, PKs... etc) i keep a list of each entity objectId and the path to the corresponding image. After saving, i can then loop through that list and get the correct server generated filename for each image... and upload the images on a seperate thread..

Posts: 1255
Joined: 10-Mar-2006
# Posted on: 22-Dec-2006 09:27:23   

Simon, What is this 'new serialization' that is extremely fast/small that you have implemented? Is this something you are sharing?

LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 29-Dec-2006 19:40:30   

v2.1 - request

Fran, i have 2 request

1 .My Project involves saving the entity as it becomes dirty (Property_Change Event). I can't have the save button in my application. It would be great to see if i can set some kind of property like Entity.SaveMode=true; so that when setting values on the fields in trigger wouldn't go back to the PropertyChanged event and other related objects. currently i am using If statement to avoid going to some places but it still is a problem.

  1. Also be able to throw exception on the Property_Change Event. Do you have any plans for this? I would love to see some resolution to these issues.

I use WinForm, .NET 2.0, SQL 2005 , LLBL V2

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Dec-2006 20:49:13   

LLBLGen wrote:

v2.1 - request

Fran, i have 2 request

1 .My Project involves saving the entity as it becomes dirty (Property_Change Event). I can't have the save button in my application. It would be great to see if i can set some kind of property like Entity.SaveMode=true; so that when setting values on the fields in trigger wouldn't go back to the PropertyChanged event and other related objects. currently i am using If statement to avoid going to some places but it still is a problem.

I don't know exactly what you mean, could you give an example?

  1. Also be able to throw exception on the Property_Change Event. Do you have any plans for this? I would love to see some resolution to these issues. I use WinForm, .NET 2.0, SQL 2005 , LLBL V2

What exactly do you mean by throwing an exception when an event is raised? Why would you want an exception on an event?

Frans Bouma | Lead developer LLBLGen Pro
LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 30-Dec-2006 06:18:07   

I don't know exactly what you mean, could you give an example?

here is the thread i am refering to. But what it is is that i have my application where there is no save button. most of the save is done in Property_Changed event. In my save method i have triggers that go and update fields of the same entity based on my business logic. since the save was called on Property_Changed event it goes back to the Property_Changed and other places where there is a reationship with the entity that i am trying to save. somehow i want to be able to save the entity when its dirty, without going back to Property_Changed event.

This thread has the example:

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=8128

What exactly do you mean by throwing an exception when an event is raised? Why would you want an exception on an event?

say i am calling my save method for an entity in Property_Changed.

my save method first validates the entity and then saves if the entity is validated. lets say there was some error so i want to throw an exception i can't if the save was called within Property_Changed event. here is the thread with example.

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=7822

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 30-Dec-2006 11:47:13   

Ok, but I don't think I can make these changes, as PropertyChanged is an event meant for bound UI controls, i.o.w. a databinding event.

If you want to save an entity when it's changed use the EntityContentsChanged event on the entity itself.

Frans Bouma | Lead developer LLBLGen Pro
LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 30-Dec-2006 22:04:28   

If you want to save an entity when it's changed use the EntityContentsChanged event on the entity itself.

That is how i used to do it in V1 but V2.0 doesnt seem to fire when the EntityContentsChanged.

example when i bind an entity to a form's text box it dosent seem to fire when you enter data. am i doing anyting wrong..i havent seen a resolution to this problem in any threads yet...

http://llblgen.com/tinyforum/Messages.aspx?ThreadID=7176&HighLight=1

here is my code, i have a form with few text box to enter employees bank. when user starts entering data. i would like to see the message box pop up. but it does not. am i doing anything wrong..same code used to work in v1 or with current version's PropertyChanged event. I would love to use EntityContentsChanged.



{
...

//Create New Bank Entity for employee
EmployeeBankEntity EmployeeBank =new EmployeeBank();
BindEmployeeBank();
...
}

       private void BindEmployeeBank()
        {
            //Remove Old Bindings
            RemoveCurrentBindings();

            //Do Control Binding
            AmountTextBox.DataBindings.Add("Value", EmployeeBank, "AmountValue", true);
            RoutingNumberTextBox.DataBindings.Add("Text", EmployeeBank, "RoutingNumber");
            AccountNumberTextBox.DataBindings.Add("Text", EmployeeBank, "AccountNumber");
            BankNameTextBox.DataBindings.Add("Text", EmployeeBank, "BankName");
            IsEmployeeBankBinded = true;

            EmployeeBank.EntityContentsChanged += new EventHandler(EmployeeBank_EntityContentsChanged);

            BankNameTextBox.Focus();
        }

        void EmployeeBank_EntityContentsChanged(object sender, EventArgs e)
        {
            MessageBox.Show("EntityContentsChanged Event Fired");
        }
Chester
Support Team
Posts: 223
Joined: 15-Jul-2005
# Posted on: 30-Dec-2006 23:57:59   

The event won't fire until the entity has actually changed, which isn't the case until the entity has a property changed. I can't tell in your setup where the reverse-binding occurs, but it shouldn't occur when the user begins typing in a text box. You'll need to trap a UI event in that case.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 02-Jan-2007 09:40:55   

Do you see the messagebox when you move to another textbox with TAB? (if you have Listboxes' bound to fields, then the binding is called 'complex' and BeginEdit is called by the form's currencymanager, which delays the event until endedit is called. )

Frans Bouma | Lead developer LLBLGen Pro
LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 03-Jan-2007 08:38:20   

No, when you tab it does not show the message box. not even when you enter something in the textbox and TAB.

I have created a small app to demostrate this. All i have is a table with firstname and lastname. when you click "New Employee" button. New Employee is created and are binded to two textbox and EntityContentsChanged is called which should show the message box. But when firstname is enterd and TAB it does not show the message box.

Is there anyway to upload or email my test app to show this problem? Let me know.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 03-Jan-2007 10:25:31   

LLBLGen wrote:

No, when you tab it does not show the message box. not even when you enter something in the textbox and TAB.

Yes, this is a known issue and nothing we can do about because winform's databinding has HARDCODED code to test for 'datatable' to overcome this. In a textbox situation, and you bind a datatable to multiple textboxes through a bindingsource, winforms databinding logic won't call BeginEdit. However when you bind a DataView it does. It also does this when you bind an entity or entity collection.

This is unfortunate as an entity can't raise any contentchanged event as long as EndEdit isn't called. This is a similar thread. Start with this message: http://www.llblgen.com/tinyforum/GotoMessage.aspx?MessageID=44946&ThreadID=7526

I have created a small app to demostrate this. All i have is a table with firstname and lastname. when you click "New Employee" button. New Employee is created and are binded to two textbox and EntityContentsChanged is called which should show the message box. But when firstname is enterd and TAB it does not show the message box.

Is there anyway to upload or email my test app to show this problem? Let me know.

You could attach it to the message, but I think it's the same issue as described in that thread.

If I were you, I'd add a save button.

Frans Bouma | Lead developer LLBLGen Pro