Dynamically creating new elements for an collection created from database entries - c#

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!

Related

What is the best way to take a small portion of items from a large RealmCollection?

I'm currently working on a Xamarin.Forms project using Realm 5.1.2. I need to take a collection of RealmObjects, filter them into a smaller set, and convert them to a UI element for displaying data based on each item. On smaller data sets, the implementation I have works well. However, when attempting to do this with a large data set (1,000,000+ items to start, filtered down to ~1000), the app slows down drastically when attempting to convert the filtered objects.
So far, I've attempted to fix this by containing my filtering process to IQueryables and IRealmCollection. I'm aware that instantiating all the objects in my final result is causing the slow down. I'm looking to add a lazy loading method, since not every element will be visible at a time (only loading 10 at a time, and request more as needed). My current implementation is:
Creating the RealmCollection once:
var filteredRealmCollection = localRealm.All<Field>()
.Where(field => field.IndexedId == input.TargetIndexId) //Use indexed parameter for initial filter
.Where(field => field.Value == input.TargetValue) //Take all fields that match the requested filter value
.AsRealmCollection();
Calling for new items as needed:
IEnumerable<FieldItemViewModel> GetFieldItemViewModels(int numberToSkip, int numberToTake)
{
return filteredRealmCollection
.Skip(numberToSkip)
.Take(numberToTake)
.Select(field => new FieldItemViewModel(field)
}
The creation of the RealmCollection runs just fine, and if I wait for the whole list to instantiate, it has the correct values. Calling GetFieldItemViewModels also works just fine. But when I try to actually use the returned IEnumerable, the app freezes up until it instantiates the entirety of filteredRealmCollection. I've also attempted to use RealmCollection[index] to get a subset of items, with similar results.
Is there a way to only instantiate the items I've requested using RealmCollection, so that I'm only loading 10 items instead of ~1000? If not, is there a different way to accomplish what I'm trying to do here?

Remove last list item from DynamoDB?

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...

The efficient way to make external data structure updater UI

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.

Dynamic column datagrid in wpf

I have a case where in the columns of Datagrid are not fixed . i.e it has to be generated depending on some conditions.
How can i store the values in the DB and display the datagrid with them using MVVM pattern.
P.S : I have a main grid and a sub grid and depending on the value he chooses in the main grid i need to form the below grid. My concern also in storing it in the DB, since there can be 5 columns or sometimes 20.
Any similar links or references will also be useful.
This can be totally done in an MVVM compliant way, but isn't necessarily trivial for a beginner, and isn't appropriate for simple applications.
One approach I like to use is to keep a collection of column descriptors serialised in the database1. The column descriptors are simply my own custom DTO data classes and contain properties related to a column, i.e. width, column type, whether it is visible, whether it's visibility can be toggled, it's ordinal, etc. This is all done using simple structs and or primitive .Net types, but specifically doesn't have any UI related data types in it at all2.
This list of ColumnDescriptors can then be serialiased to and from XML, and stored in the database either in an nvarchar or XML column. Especially on SQL Server an XML column is better as you can natively query deep into the XML structures stored in the database column.
As it is a UI layout thing, it is up to the view to query the right set of column descriptors from the database, I then pump that collection through a static GridColumnFactory class which iterates the descriptor objects and creates me the appropriate grid columns and assigns the appropriate values to them. Once the factory returns that collection the view can then add them to the DataGrid's columns collection.
The benefits of this approach:
If I swap out the DataGrid that is used (i.e. swap from one vendor to another, say DevExpress to ComponentOne or native WPF), I can simply change the types of columns returned from the factory class
If I swap anything in the UI then I don't need to touch the column descriptors that are stored.
Serialising to and from XML means that if I do add/remove properties from the descriptors then older stored copies can still be accommodated, they aren't instantly broken the moment I release an update
One of the best features of all is that I can change the stored column layouts with a simple SQL statement, I don't have to also release compiled code
One last thing - using column descriptors makes it trivial to implement a user specified layout, i.e. when you let them drag columns around and then want to save the layout for next time
If I want to get really funky, the column descriptors can be returned from a webservice
1 For a website these could also be stored in a loose XML file which is then read in and kept in cache.
2 For this approach you should always avoid using specialised or vendor specific data types, as they don't necessarily serialise well (if at all), and will become a weak point in the future - these will be the most likely things you have to change, and if these change you break any stored descriptors you've already got.

Populating a Dictionary with PdfOutlines

So I am attempting to write a program that combines a PDF from a list of PDF's that are already available. I've got most of it done to this point, but I'm having an issue with one step in particular. I'm also writing this in c# if that isn't apparent.
I have an array of strings that contains a category name, and for each category name I want to create a variable of type PdfOutline that gets initialized to null that I can iterate through later in the program.
I've tried to look into this myself and it seems like dictionary is the way to do it, but I'm not really sure how to go about it. Firstly, is making a dictionary the right way to do it and secondly I need help with implementation.
Thanks for your time!
Something like the following would work (not syntax-checked this, sorry):
// This requires the array of Categories to have no duplicates.
public Dictionary<string, PdfOutline> BuildUpMyCollectionOfOutlines(string[] categories)
{
return categories.ToDictionary(cat => new KeyValuePair<string, PdfOutline>(cat, null));
}
If you do it this way, then you can later consume the result as such (although having a function to do this is silly, is just my way to show you how to consume it):
public PdfOutline GetOutlineByCategory(Dictionary<string, PdfOutline> outlines, string category)
{
// This will be problematic if the category isn't actually in the dictionary.
return outlines[category];
}
Whether you should use a Dictionary<string, PdfOutline> versus something else, like a List<KeyValuePair<string, PdfOutline>> depends on 1) how many of these you'll have and 2) how you'll be accessing them. For example, if you have 10,000 of them and you need to randomly and repeatedly find them by Category name, then the Dictionary is the right approach because it hashes things for quicker searching (think an index in a table in a database). However, if you have 10,000 but only need to find 2 of them, or vice versa, only have 10 of them, then the overheads in building up that quick-searching capability is wasted. So Dictionary vs other is best answered by the question, "If this was in a database table, would you index it?"

Categories

Resources