I'm using DynamoDB / Amazon Web Services with their SDK Object Persistence Model. I have an object type that has some basic parameters and some lists that are stored. This works fine and the lists are stored as string sets on the DB. To save the objects back to the DB I'm simply calling:
context.Save<AwsProject>(project);
This is working fine as long as the list isn't empty. If I have had items in the list and then remove the last one, creating an empty list, this does not save, the last item stays in there...
What am I missing? Is there something else I need to do to clear out that last value?
DynamoDB doesn't support empty sets. See the very last sentence of the DynamoDB Naming Rules and Data Types article. If your list is empty, you should completely delete the attribute that is storing the list.
Ok I just got back to this and I think I must have been doing something else in my code that was not letting it remove properly. I worked on a few other things and fixed some issues in the saving and when I came back to address this it's gone. Removing the last item from my collection and then using the context to save the object now removes the attribute without me expressly doing it. Sorry for the confusion but it looks like their API does indeed handle this as I would expect...
Related
I currently have an item database with about 500 (and counting) items in it that's loaded into an array once when the application starts. These items are often accessed (by index) but the array and its contents are never modified during runtime. I'm now needing to create variants of certain items in the database and I'm hoping to do it dynamically during runtime to avoid creating a bunch of item duplicates in the database file itself, as it would more than double the size of it. Since the database will grow in time, I can't simply start assigning the variant ids where the regular item database ids end, as these ids will be saved into user's profiles and they cannot change later.
I've attached a screenshot to make it a little more clearer what the items look like in case it helps. What I'm trying to accomplish in practice is to create X amount of variants of for example the "refined_spear" item for the purpose of cosmetic effects on the items in my game. So for the refined_spear, I'd be creating a duplicate of it, assign it its own id and give it whatever cosmetic effect it should have, and then add it to the items collection.
The way I see it I have a couple of options:
Use a list instead of an array. This would mean that it's no longer viable to access items by index. Not sure how big of a performance hit that would bring.
Create a larger array than is needed, and give the item variants id's that I know the regular database items will never reach. This would leave the array with a ton of null values, but would allow me to continue accessing items by their id.
Simply add the new items in the database file manually
Any input from people wiser than me would be much appreciated!
I have a class contains a lot of properties. One of them needs a special UI to be edited.
The user may press edit to this property in the UI then he make changes and either press OK or Cancel
e.g.
class A{
private List<Employee> employees;
public void EditMyEmployees(){
EmployeeEditorForm editor = new EmployeeEditor(employees);
if(editor.ShowDialog() == DialogResult.OK){
employees = editor.GetEditedEmployeesList();
}
}
}
The problem in the previous code that the editor has a copy of the reference to the employees List
and when the editor makes any edits in the List it will be reflected in the original object.
So, pressing OK or Cancel will have the same effect (the object is already updated) and no need for the step
employees = editor.GetEditedEmployeesList();
I know that making deep copy for the employees array before sending it to the editor will solve the problem but still I think this is not the efficient way to do it
I am looking for a design pattern that can make this in a better way.
You don't necessarily need to deep copy the whole collection. You just need to keep track of the elements that changed. Within your EmployeeEditor, use three lists (List<Employee> to keep track of:
Added employees
Removed employees
Changed employees
Upon Cancel, you would need to remove the "added" items, add back the "removed" items, and replace the changed items with their original state.
Note that the changed employees list would need to keep a copy of the original state of the object. If the Employee class has some sort of unique id, you can match cased on that id. Otherwise, the "changed" list would need to be a List<Tuple<Employee, Employee>> so that you can store the matching items.
Also note that, when changes happen in the employees list, you also need to make necessary changes in those three lists. For example, if an new employee is added and then removed, you also need to remove that record from the "added" list. Or it is possible an employee is changed and then removed, in which case you also need to remove from "changed" list.
Having said all this, if I were you, I would make a decision based on the expected use cases and real performance problems (not anticipated performance issues). It is very likely that simply deep copying your collection is the simplest and least error prone way.
There are two kinds of changes involved here: (1) changes to the list (Add / Remove) and (2) changes to individual elements of the list (employees in this case).
Now, part of the problem comes from the semantics of OK/Cancel. If you restrict the scope of these two buttons to changes of the second kind (i.e., changes to the elements of the list), you will be able to handle Remove with a confirmation dialog on this particular action ("Remove such and such"?). For the Addition you don't need anything special, just add a new element to the list. If the user changes their mind they will still have the Remove action available.
For changes on a particular element (second kind) you can use the command pattern as mentioned in the comment. More simply, you could initialize temporary variables for all the fields your editor displays from the element under edition. As the user modifies some values your editor will update the corresponding temporaries. If the user press Cancel you will simply forget those changes (or reinitialize them from the element). If the user press Apply (yes, you should include the Apply button also,) you will now write each of the temporary values onto the corresponding element's attribute. If the user hits OK you would Apply and Close.
Lets say my c# model updated while correspondent collection still contains old documents, I want old and new documents to coexist in the collection, while using only new version of c# model to read them. I wish no inheritance is used if possible. So I wonder which of this issues are solvable and how:
there is a new property in c# model which does not present in database. I think it never should be an issue, Mongo knows nothing about it, and it will be initialized with default value. The only issue here is to initialize it with particular value for all old documents, anybody knows how?
one of property has gone from model. I want MongoDb to find out there is no more property in c# class to map the field of old document to, and to ignore it instead of crashing. This scenario probably sounds a bit strange as it would mean some garbage left in database, but anyway, is the behavior possible to implement/configure?
type if changed, new type is convertible to old one, like integer->string. Is there any way to configure mapping for old docs?
I can consider using inheritance for second case if it is not solvable otherwise
Most of the answers to your questions are found here.
BsonDefaultValue("abc") attribute on properties to handle values not present in the database, and to give them a default value upon deserialization
BsonIgnoreExtraElements attribute on the class to ignore extra elements found during deserialization (to avoid the exception)
A custom serializer is required to handle if the type of a member is changed, or you need to write an upgrade script to fix the data. It would probably be easier to leave the int on load, and save to a string as needed. (That will mean that you'll need a new property name for the string version of the property.)
Hello fellow developers.
First of all I apologize beforehand for the wall of text that follows, but after a day going crazy on this, I need to call for help.
I've stumbled across a problem I cannot seem to solve. I'll try to describe the scenario in the best possible way.
Task at hand: in an existing Asp.Net Mvc application, create a lookup table for an integer field, and use the textual value from the lookup in the editing view. When saving, we must first check if the lookup already has a corresponding text value for the same Root ID. If there is, use that. Otherwise, create it and then use it.
The structure:
The data model is a graph of objects where we have the root object, a collection of level A child objects, and every level A child object has a collection of level B child objects, so something like this:
Root (with fields)
Level A child (with fields) x n
Level B child (with fields) x n
The field we have to handle is on the LevelB objects.
There is a single Mvc view that handles the whole data. For collection objects, all fields are named like levelA1levelB1MyField, levelA1levelB2MyField, etc so every single field has unique name during the post. When the post happens, all values are read through a formCollection parameter which has average 120/130 keys. The keys are isolated by splitting them and looping on the numerical part of the names, values are read and parsed to the expected types and assigned to the object graph.
The datalayer part backing the object graph is all stored procedures, and all the mapping (both object to sproc and sproc to object) is hand written. There's a single stored procedure for the read part, which gets multiple datasets, and the method calling it reads the datasets and creates the object graph.
For the saving, there are multiple sprocs, mainly a "CreateRoot" and "UpdateRoot". When the code has to perform such tasks, the following happens:
For create scenario, "CreateRoot" is called, then the sprocs "CreateLevelA" and "CreateLevelB" are called in loop for each element in the graph;
For update scenario, "UpdateRoot" is called, which internally deletes all "LevelA" and "LevelB" items, then the code recreates them calling the aforementioned sprocs in loop.
Last useful piece of information is that the "business objects graph" is used directly as a viewmodel in the view, instead of being mapped to a plain "html friendly" viewmodel. This is maybe what is causing me the most trouble.
So now the textbox on the view handles an "integer" field. That field must now accept a string. The field on LevelB must remain an integer, only with a lookup table (with FK of course) and the text field from the lookup must be used.
The approaches I tried with no success:
My first thought was to change the datatype on the property MyField from integer to string on the object, then change the sprocs accordingly and handle the join at sproc level: I'd have a consistent object for my view, and the read/write sprocs could translate from string to integer and viceversa, but I can't do that because the join keys to retrieve the integer when writing are part of the Root item (as I stated in the first lines of this wall of text), which I don't know in the CreateLevelB sproc, and changing the whole chain of calls to pass those parameters would have a huge impact on the rest of the application, so no good.
My next try was to keep things "as they are" and call some "translation methods": when reading, pass the integer to the view, and there call the translation method to display the text value. When saving, use the posted text to retrieve the integer. The save part would work, I'd have all the parameters I need, but for the read part, I'd have to instantiate the "data access layer" and call its method at View level, and there's no need to explain why that is a very bad choice, so I ruled this out too.
Now I'm out of options (or ideas anyway). Any suggestion to solve this is very welcome, and also if something is not clear enough just point it out and I will edit my post with more accurate information.
Thanks.
This is not a real answer but you could rip out all sprocs and use the updating facilities of an OR mapper. This will resolve all the layering issues. You just update data how you see fit and submit at the end.
I guess this would also make the questions around "should I use an int or a string" go away.
Edit: After reading your comment I thought of the following: Do not implement alternative 1. You rather want to sacrifice code quality in the view than in the data storage model. The last one is more important and more centrally used.
I would not be too concerned with messing up the view by calling the DAL from it or the like. Changes in a view are localized and do not mess up the application's architecture. They just degrade the view.
Maybe you could create a view model in your controller and do the translations between DAL-model and view model? Or is that pattern not allowed?
We inherited some C# code as part of a project from another company which does URL redirects that modifies the existing query string, changing values of items, adding new params, etc as needed. The issue however is that the code is buggy at best, and ends up duplicating items in the query string instead of updating them properly. The code works on the first pass but on additional calls the duplication issues become apparent.
Ex: MyPage.aspx?startdate=08/22/09&startdate=09/22/09
Instead of duplicating the item it needs to be either updated with the new value if it already exists, or added if not there already.
Is there a C# class or set of functions for handling query strings, allowing a simple means to access and update/add parameters that gets around these issues instead of the blind add approach that seems to be in use now with the code? This needs to be able to handle multiple parameters that may or may not exists at all times and be added and updated on subsequent calls.
We would sooner use existing logic than recreate something if possible so as to get this resolved quickly in a semi standard way for future maintainability and reuse.
Yes I would suggest converting the querystring to a collection by using HttpUtility.ParseQueryString()
You can then find/add/update/replace values directly in the collection, before re-creating the querystring from this collection.
This should make it easier to spot duplicates.
You can access and manipulate all values of your Querystring through the Request.QueryString collection. Here's a link.
this seems a basic design problem.
instead of updating the current query string, what SHOULD be done is simply adding all the parameters to the base at every time.
sure, you CAN update it, but (pseudocode)
if querystring exists
then update query string
else
add query string
will get crazy when you start using more than 1 variable.
redesign would be best, effort allowing.
The WCF REST Starter Kit available on ASP.NET also include a new "HttpQueryString" helper class that will most likely be included in the .NET 4.0 time frame into the base class library.
See an excellent screencast on how to use this utility class here:
http://channel9.msdn.com/shows/Endpoint/endpointtv-Screencast-HttpClient-Query-String-and-Form-Input-Management/
Marc