This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
Hi, I have a problem which can be re-produced with below steps: 1) Create entity DbObject: 2) Create entity DbCodeName: 3) Create entity Department: 4) Run testing code: Department o1 = new Department(); Department o2 = new Department(); } The code will fail for second run with error: If I uncomment //uow.SaveChanges(); it will be ok. I understand the reason is same Code already exists in table. The question is: Is it system designer behavior or bug? Thanks |
|
|
This is a slightly odd consequence of by-design behaviour. LightSpeed uniqueness validation checks the entity against the database itself, not the entities in memory. This is because the database may well contain rows that have not been loaded into entities, and we need to ensure that the value is unique even with respect to those unloaded rows. However, the database does not know if entities have been removed (and therefore rows are scheduled for deletion). So a uniqueness clash with an entity that's scheduled for deletion will result in a validation failure, even though everything would actually have been all right once all the changes were considered. Our suggestion in this case would be to perform a SaveChanges between the delete and the add (as per your commented-out line). You can still ensure atomicity by enclosing both SaveChanges calls -- the one to delete and the one to add -- in a transaction. |
|
|
Hi, Ivan, There still may be problem. Consider I provide a basic maintenance function for Department, user can add/edit/delete records freely and click Save button to save all changes finally. Because I cannot control the user's behavior, user may: Then how I can control SaveChanges to issue Remove command at first? Thanks, |
|
|
You could do this by extending the approach discussed previously: begin a transaction when the user enters the edit screen, perform a SaveChanges after each Add or Remove (well, really it would be needed only after each remove), but do not commit the transaction until the user hits Save. Note that depending on what database you are using this may run into issues with the database timing out the transaction. (And it would certainly be unsuitable if there was intensive database activity going on, because you don't want to hold locks for long periods, but it doesn't sound like this would be a big issue in your scenario.) Give it a quick test and see. If the long-running transaction isn't an option for you, we have some other ideas, but these are likely to have a bit more of an impact on your design, so we would need to know a bit more about the design of your application. We would also need to know what database you are using. |
|
|
Hi, Ivan, My current database is SQL Server 2005. However, I'm only in early evaluation stage with LightSpeed/Sliverlight/WCF, so there is no complete design. What I do now is to confirm the posibility of such a combination. And maybe I'm just thinking in the wrong C/S way. Here are my thoughts about Department basic table maintenance: 1) SilverLight frontend with Datagrid control to present data (this is not existed now) I searched forum and one post said LightSpeed will fully support WCF and I would like to see full CRUD samples with WCF. Thanks,
|
|
|
There are actually several design considerations here which I will discuss separately. Firstly, the LightSpeed load/save side of things, inside the WCF service. Because services are stateless, you will be wanting to have a unit of work per request, i.e. lasting only for the duration of the service call. This means we don't have any concern about long-held locks: you begin a unit of work, apply your changes, save the changes and dispose the unit of work. Units of work should be short-lived wherever possible and a WCF-based design is a good fit for this. Now we need to consider the service interface. There are two possible approaches here: a "change log" interface, in which the client (the Silverlight app) sends a list of differences (add this, remove that, edit the other), or a "replace" interface, in which the client sends a list of departments, and this list completely replaces the existing one. The "replace" interface is simpler for both client and server, but it is suitable only for small sets of data where there is minimal risk of two users editing the data at the same time. The service interface in turn drives the service implementation. If you adopt the "replace" interface then your LightSpeed code within the service looks like the code you posted at the top of the thread: begin a transaction, remove all the existing departments, save changes, add all the new departments, save changes, commit the transaction -- all this within the scope of the single service call. If you adopt the "change log" interface then you will need to begin a transaction, load the entities from the database, apply the "remove" changes, save changes, apply the remaining changes, save changes, and finally commit the transaction. You will also need to design a change log message, and you will need in your Silverlight client to figure out what the changes are so that you can build that message and call the WCF service. Notice that this message will need to explicitly specify the nature of changes (add, edit, remove), which means your service implementation can easily scan the list to find the removes and do them first. That brings us to the final issue, which is that you can't use LightSpeed on the Silverlight end to track entity state (e.g. deleted / changed / new). LightSpeed is built for the desktop CLR, and we do not currently expect to produce a Silverlight build (because Silverlight doesn't have any relational database support). So you will need to come up with your own design for entity management and change tracking on the Silverlight side. We internally have a sample of full CRUD using WCF but it is in a bit of a rough state at the moment. I have let JB know that you are keen to see it and he will try to update it and put it out on the blog (http://www.mindscape.co.nz/blog/) early next week. I believe this uses a "change log" interface but I think it uses LightSpeed at both ends, which as mentioned will not be possible in a Silverlight scenario -- however hopefully it will give you some useful pointers. |
|
|
Hi, Ivan, Thank you for your valuable and complete explanations. I'll think and try. Regards,
|
|