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
|
Hello all, I'm using the most current nightly build. This is my first time posting, and I desperately need assistance if at all possible. The issue is that I'm able to make updates to this multi-table view within SQL Management Studio (proving that the view is in fact updatable), but I am unable to make simple updates via lightspeed. Here is what I've done thus far...
I know this type of thing is possible within lightspeed, because I'm doing it in a different application for the same project where other views are involved. I'm just not sure what I'm missing here. Any help would be greatly appreciated! Thank you, Jason UPDATE: I've found that in every place I've done this successfully, it was actually not the same after all. These involved inserts, rather than updates. Apparently, the SQL output (as seen from the context logger) includes every field from every table, and thus lies the issue. So the real question of the hour is, how can I update a subset of fields, rather than specifying all of the fields in the update? I hope this also helps anyone else trying to update through views. Thanks in advance! UPDATE 2: I've figured it out! For anyone interested, here is the solution... Once I found the root cause, I then queried the forums a little differently. I came across Ivan's solution to entity subset querying here: Partial Entity Update I then crafted the solution as the following:
UPDATE 3: Also remember that if you're looking to bulk update back to a null value for any of your fields from an anonymous method such as the one used above, use DBNull.Value. ie:
Solved. |
|
|
Solved... Or so I thought... UPDATE 4: Everything above worked flawlessly, until... it came time to bind to a grid control and update from this. this obviously does not work, as the SQL generated shows of course the complete field set of the entire extended view, rather than just the fields that I wish to update. How might I go about updating only a subset of data, rather than the full set, via a grid control of some kind? This is an emergency and any help is truly greatly appreciated!!!!! Put another way... I realize that any changes to the control automatically registers the update to the full view object with the unitOfWork. Is there a way (via overrides even?) to specify sending only a subset to that unitOfWork, so that when I call SaveChanges(bool), it doesn't try and update the entire view? Am I able to do this via aggregates? I'm very new to this framework having just purchased it, and I'm truly at a loss here. Thank you!!!! (*Help!) UPDATE 5: I've figured it out! I'm posting the solution for anyone else who might also need assistance in this area. I again stumbled across a post made by Ivan (He is quite masterful with his product), stating that when marking a field in the designer as "Load Only", it does NOT affect the code. I do not know why this is, but I'm sure they have their reasons. The solution in making a field's data available to the control, WITHOUT having certain fields' data updated to the database on SaveChanges(bool), is to go into the designer code and mark the FIELDS as readonly for all tables in the underlying multi-table view which are not part of the singular table you wish to update from that view. I'll include an example from my project, so that you can understand exactly what I mean. Code file to update: Now... If you take a look at the image below which displays code from the file in the image referenced above, you'll find the 'readonly' keyword applied to each of the fields which are not intended to be updated. In fact, I have each field prefixed with the table that field comes from, so it is very easy for me to see at a glance, which table's fields each field belongs to (best practices being what they are and all...). After this was completed, my updates finally worked, and worked flawlessly, even in a view which contains fields from 6 different tables! You guys at Mindscape have an absolutely sound product, and one I LOVE using. My only request would be that the documentation for your product be updated ASAP. The time this product should save me is partially lost in my having to look things up which are not in the documenation. Thank you again! Solved! Jason Nickle PS... As a sidenote, if any changes are made to this entity, the code in that file will be readily regenerated and the readonly attributes must be re-applied. I consider this more of a workaround, than a real solution, though it is a solid solution nonetheless. If my posts here are read by the Lightspeed crew, can you please post a better solution? In any case, this solution is the only one which has worked for me, and it does work flawlessly. Be warned however, that if you do not flag each and every field you wish to make updatable in code as "Load Only" FIRST in the designer, you'll receive "ref/out" errors until you do so. Tip: I simply add a text file to the folder containing my model, and copy/paste the 'field' section of the entity which I've altered with readonly attributes. If I make any changes and the code is regenerated, I simply copy/paste it back over into the auto-generated file. Saves time and makes the issue a non-issue. |
|
|
Hi Jason, Thanks for the detailed post - very valuable! I will have a look at updating the documentation around using views based on your feedback :) One suggestion to avoid having to muck around with the generated code is for any properties which you want to maintain control over is to set the "Generation" property on these to be "None" and then specify the field and property declarations for these in a partial (you can just copy/paste over the current implementation).
|
|
|
Hi Jeremy, My pleasure! Thank you so much for the kind words, and thank you for so quickly committing to update the documentation! I've done as you suggested, and found that when I select the 'None' option for the 'Generation' property, I disable support for UI component mappings. I originally thought I was good, but this too is a no-go. There is currently no option within your lightspeed designer to make a field 'readonly' in code. If there was, this would be permanently fixed. What you proposed would work, if I did not need the data coming from the other fields. Thanks, Jeremy! Mindscape support really is as good as I've heard it is! Very responsive, accountable, and GREAT to work with! Thank you, Jason Nickle |
|
|
Jeremy, I don't know how difficult this would be to do within your lightspeed classes (I don't have access to source), but if you added a property to the entity within the designer, to accept a bool setting regarding whether or not to exclude it from updating during the unitOfWork save, lightspeed would have absolute first class support for updatable views, which is HUGE. This would also affect performance as well, in that as you know, Microsoft SQL Server for example has a hard limit for a single update with a figure of 2100 (#params * recordCount). Example:
It goes without saying that views have always been attractive for data loads in that they are very conducive to dynamic SQL, permissions control, and UI data surfacing. It is highly beneficial not to have to apply permissions to base table objects. Additionally, your framework already really does things right, with constructing queries and executing against the server from server context, without having to pull the entire result set back first to apply conditions to queries (linq/query objects). It just seems like it has everything, except for this. What are your thoughts? Is this at all possible? Thank you, Jason |
|
|
Check out using the [UnversionedPartialUpdate] attribute on your entity, thats likely to achieve what you want. It was added as part of this forum discussion: http://www.mindscapehq.com/forums/thread/4551
|
|
|
I apologize for not returning a response sooner. I've been involved in other aspects of the project, which has delayed my return. Now, as to the solution you proposed... I spent some time and took a good look at that thread, however I see that 'last in wins' is not observed, but rather concurrency is enforced without the ability of the developer to specify this preference. Is this correct? Incidentally, as I was reading everything, I couldn't help but smile as that is the PRECISE functionality and for the PRECISE reason I need these partial updates as well (heck, even involving a field='Qty'!). All of the suggestions made therein, were exactly what I would be suggesting now and need at the present. Is this implemented as of current? Thank you very much! Thank you, Jason Nickle Senior Software Developer PS... I absolutely love you guys. Best support in the industry, hands down. |
|
|
Actually its the opposite with [UnversionedPartialUpdates]. Our standard operating procedure is last in wins. If you are using LockVersion to apply concurrency then that is checked prior to an update and an exception is thrown if the database is not in the expected state. We also only sent down specific field updates because we could make assumptions about the database not having changed due to the concurrency check. The introduction of [UnversionedPartialUpdates] was to apply the same "only send down the changes" logic while ignoring the dirty data problem that might be involved with doing that. tldr; If you want partial updates and concurrency, use a LockVersion field on your entity to enable concurrency checking. If you just want the partial update you can look at using [UnversionedPartialUpdates]. ps. Thanks for the feedback - much appreciated :)
|
|
|
Jeremy, In that case, you've just made for a very excited developer. That is an elegant solution and I will attempt to implement that as we speak! Thank you sir. Thank you, Jason |
|
|
Now if I can only figure out deletes/inserts when hooked up to a Winforms UI grid, I'll be set for this project!...... |
|