Best practice to gather data across multiple fragments before db write - c#

Android application using .net/Xamarin. I have several fragments in a view pager. If I were to have some data collected on each fragment in the pager incrimentally, what is the best way to gather all the data as I go and only write to the db once, at the end? I am using a sqlite db. But, lets say for example there are two fragments in the pager. First fragment collects user name, first and last name. Then, a next button takes them to the second fragment for address and phone number. After they are done, they click save and then I can write to the db one I have gathered all of the info.
Sure, I could write to the db after each fragment, but is that really the best practice? I dont think I want to pass the data from fragment to fragment. That might seem like a way to go with the above example but I dont think it scales well, for example if I end up later with 5 fragments collecting data.
I have been thinking about a singleton class. I have read that they should be avoided at all costs but maybe this is an application suited for them? I could create a singleton with all my properties and as I go through the fragments and build data, they are saved in the singleton. At the end, I basically write the singleton data to the db and clear it out, ready for the next time. I dont think I have to worry about thread safety in this use case or at least, I can write it so it is not an issue.
Is that the way to go? Other thoughts or ideas?
Thanks!
Mike

A singleton is used when you need to manage a resource, such as a database connection. In this case, I would recommend against using a singleton just to store data.
The way you propose to use the singleton isn't much different than passing an object around, the only difference being that with a singleton, you can make a request for the object you are populating.
The way you could do it, would be to have an object representing each fragment. This would allow you to initialize and have fragment dependent logic (such as validation) within a given class.
You would then have a more generic object, one that will hold the information from all the fragments which will be eventually saved to the DB. You can pass this object around from one fragment to the next, and each fragment populates the bits it is interested in.

Related

C# - Variable and List accessible in whole project

Is it possible to make a variable or a List of items accessible to the whole project?
My program selects an object in one view and a I want to have access/change it another one.
I know this not the best workaround and it would be better to use a MVVM-pattern for this, but it seems a big effort to implement this properly just for this simple usecase of one ot two variables/lists.
Sharing data can be done in multiple ways.
One interesting way could be to cache the data, have a look at this for example : https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/walkthrough-caching-application-data-in-a-wpf-application?view=netframeworkdesktop-4.8
I would recommend against using any global variables, I would also recommend not using static variables either as you might open yourself up to sharing data between users for example.
In this example, when you need the data, you check if you have it in the cache, if not you load it from wherever ( db, file, api, whatever your source is) and then you simply read it from the cache wherever and whenever you require it.
If you need to update it, then you make sure you update it to whatever storage mechanism you have and then you reload the cache. This is a good way to keep things in sync when updates are needed without complicating the application, its testing and the maintenance.

Remember data in database

I'm preparing WinForm application with local DB. I want to remember changes, when somebody will leave application, he decide to save or discard changes. I expect to have three tables, and about 1000 rows in every table. On one window I have three tables which can be modified in every time. So for I have found some solution and I had use the Local method on context. eg.
people.DataSource = dbctx.People.Local.Where(...).ToList();
I recently I try to use dynamic linq query, and I couldn't use when I access to dbctx with Local. Is something better TransactionScope, IEditableObject? How to use it.
If they close the winforms application entirely (losing any in memory storage options) then you will need to use a store of some sort (database, file etc), as you are already using a database it sounds like your best option would be to store it in there.
If you are concerned about space etc, you could simply serialize the in memory objects (perhaps to json) and store it against the user record, then next time they log in/ come back you can deserialize it back to memory and they can carry on.
If you choose this option I would recommend using Json.Net:
To serialize your in memory records use:
string json = JsonConvert.SerializeObject(people);
And deserialize back out:
var people = JsonConvert.DeserializeObject<People>(json);

Designing app to load, edit, and save hierarchical data

I am writing a GUI that will be integrated with SAP Business One. I'm having a difficult time determine how to load, edit, and save the data in the best way possible (reliable, fast, easy).
I have two tables which are called Structures and StructureRows (not great names). A structure can contain other structures, generics, and specifics. The structures rows hold all of these items and have a type associated with them. The generics are placeholders for specifics and the specifics are an actual item in inventory.
A job will contain job metadata as well as n structures. On the screen where you edit the job, you can add structures and delete structures as well as edit the rows underneath them. For example, if you added Structure 1 to Job 1 and Structure 1 contains Generic 1, the user would be able to swap Generic 1 for a Specific.
I understand how to store the data, but I don't know what the best method to load and save the data is...
I see a few different options:
When someone adds a structure to a job, load the structure, and then recursively load any structures beneath it (the generics and specifics will already be loaded). I would put this all into an Object Model such as List and each Structure object would have List and List. When I save the changes back to the database, I would have to manually loop through the data and persist the changes.
Somehow load the data into a view in SQL and then group and order the datatable/dataset on the client side. Bind the data to a GridView so changes are automatically reflected in the dataset. When you go to save, SQL / ADO.NET could handle this automatically? This seems like the ideal solution, but I don't know how to actually implement it...
The part that throws me off is being able to add a structure to a structure. If it wasn't for this, I would select the Specifics and Generics from the StructureRows table, and group them in the GUI based on the Structure they belong to. I would have them in a DataTable and bind that to the GridView so any changes were persisted automatically to the DataTable and then I could turn around and push them to SQL very easily...
Is loading and saving the data manually via an object model the only option I have? If not, how would you do it? I'm not sure if I'm just making it more complicated then it needs to be or if this is actually difficult to do with C#, ADO.NET and MS SQL.
The HierarchyID datatype was introduced in SQLServer 2008 to handle this kind of thing. Haven't done it myself, but here's a place to start that gives a fair example of how to use it.
That being said, if you aren't wedded to your current tables, and don't need to query out the individual elements (in other words, you are always dealing the job as a whole), I'd be tempted to store the data for each job as XML. (If you were doing a web-based app, you could also go with JSON.) It preserves the hierarchy and there are many tools in .NET for working with XML. There's also a built-in TreeView class for winForms, and doubtless other third party controls available.

Web application to allow users to pick and choose objects used as building blocks?

I'm currently developing an application using ASP.NET MVC, and now I need to create an interface (web page) that will allow the users to pick and choose from a set of different objecs, the ones they'd like to use as the building blocks for constructing a more complex object.
My question is supposed to be generic, but to provide the actual example, let's say the application that will allow users to design pieces of furniture, like wardrobes, kitchen cabinets, etc. So, I've created C# classes representing the basic building blocks of furniture design, like basic shapes (pieces of wood that added together form a box, etc), doors, doorknobs, drawers, etc. Each of these classes have some common properties (width, height, length) and some specific properties, but all descend from a basic class called FurnitureItem, so there are ways for them to be 'connected' together, and interchanged. For instance, there are different types of doors that can be used in a wardrobe... like SimpleDoor, SlidingDoor, and so on. The user designing the furniture would have to choose wich type of Door object to apply to the current furniture. Also, there are other items, like dividing panels, shelves, drawers, etc. The resulting model of course would be a complete customized modularly designed wardrobe or kitchen cabinet, for example.
The problem is that while I can easily instantiate all the objects that I need and connect them together using C#, forming a complete furniture item, I need to provide a way for users to do it using a web interface. That means, they would probably have a toolbox or toolbar of some sort, and select (maybe drag and drop) items to a design panel, in the web interface... so, while in the browser I cannot have my C# class implementation... and if I post the selected item to the server (either a form post or using ajax), i need to reconstruct the whole collection of objects that were already previously chosen by the user, so I can fit the newly added item... and calculate it's dimensions, etc. and then finaly return the complete modified set of objects...
I'm trying to think of different ways of caching, or persisting theses objects while the user is still designing (adding and deleting items), since there may be many roundtrips to the server, because the proper calculation of dimentions (width, height, etc of contained objects) is done at the server by methods of my C# classes. It would be nice maybe to store objects for the currrent furniture being designed in a session object or cache object per user... even then I need to be able to provide some type of ID to the object being added and the one being added to, in a parent owner kind of way, so I can identify properly the object instance back in the server where the new instance will be connected to.
I know it's somehow confusing... but I hope this gives one idea of the problem I'm facing... In other words, I need to keep a set of interconnected objects in the server because they are responsible for calculations and applying some constraints, while allowing the users to manipulate each of these objects and how they are connected, adding and deleting them, through a web interface. So at the end, the whole thing can be persisted in a database. Idealy I want even to give user a visual representation or feedback, so they can see what they are designing as they go along...
Finally, the question is more so as to what approach should I take to this problem. Are C# classes enough in the server (encapsulating calculation and maybe generating each one it's own graphical representation back to the client)? Will I need to create similar classes in javascript to allow a more slick user experience? Will it be easier if I manage to keep the objects alive in a session or cache object between requests? Or should I just instantiate all objects that form the whole furniture again on each user interaction (for calculation)? In that case, I would have to post all the objects and all the already customized properties every time?
Any thoughts or ideas on how to best approach this problem are greatly appreciated...
Thanks!
From the way you've described it, here is what I'm envisioning:
It sounds like you do want a slick looking UI so yes, you'll want to divide your logic into two sets; a client-side set for building and a server-side set for validation. I would get heavy on the javascript so that the user can happily build their widget disconnected, and then validate everything once it's posted to the server.
Saving to a session opens a whole can of webfarm worms. If these widgets can be recreated in less than a minute (once they've decided what they like), I would avoid saving partials all together. If it's absolutely necessary though, I would save them to the database.
If the number of objects to construct a widget is reasonable, it could all come down at once. But if there are hundreds of types of 'doors' you're going to want to consider asynchronous calls to load them, with possible paging/sorting.
I'm confused about your last part about instantiating/posting all objects that form the whole furniture. This shouldn't be necessary. I imagine the user would do his construction on his client, and then pass up a single widget object to the server for validation.
That's what I'm thinking anyway... by the way, hello StackOverflow, this is my first post.
You might want to take a look at Backbone.js for this kind of project. It allows you to create client-side models, collections, views and controllers that would be well suited to your problem domain. It includes built in Ajax code for loading/saving those models/collections to/from the server.
As far as storing objects before the complete object is sent to the server, you could utilize localStorage, and store your object data as a JSON string.

Database handling in applications

This is a bit of difficult question to ask but any feedback at all is welcome.
Ill start by the background, I am a university student studying software engineering last year we covered c# and I got myself a job working in a software house coding prototype software in c# (their main language is c++ using QT) after producing the prototype it was given to some clients which have all passed back positive feedback.
Now I am looking at the app and thinking well I could use this as a showcase with my CV esp as the clients who used the software have said that they will sign something to reference it.
So if I am going to do that then I had better get it right and do it to the best I possibly can. so I have started to look at it and think where I can improve it and one of the ways in which I think that I can is the way it handles the database connections and the data along with it.
the app itself runs along side a MySQL server and there is 6 different schemas which it gets its data from.
I have written a class (called it databaseHandler) which has the mysqlconnection in it ( one question was about if the connection should remain open the whole time the app is running, or open it fire a query then close it etc) inside this class I have written a method which takes some arguments and creates its query string which it then does the whole mysqlDataReader = cmd.executeReader(), this then returns the reader back to where ever it was called from.
After speaking to a friend he mentioned it might be nice if the method returned the raw data and not the reader, therefore keeping all the database "stuff" away from the main app.
After playing around I managed to find a couple of tutorials on putting the reader data into arrays and arraylists and passing then back, also had a go at passing back an array list of hashtables - these methods obv mean that the dev must know the column names in order to find the correct data.
then I stumbled across a page which went on about creating a Class which had the attributes of the column names and created a list which you could pull your data from:
http://zensoftware.org/archives/248 is the link
so this made me think, in order to use this method, would I need to create 6 classes with the attributes of the columns of my tables ( a couple of tables has up to 10-15 columns)? or is there a better way for me to handle my data?
I am not really clued up on these things but if pointed in the right direction I am a very fast learner :)
Again I thank you for any input what so ever.
Vade
You have a lot of ideas that are very close but are pretty common problems, but good that you are actively thinking about how to handle them!
On the question about leaving the connection open for the whole program or only having it open during the actual query time. The common (and proper) way to do this is only have the connection open as much as you need it, so
MySqlConnection cn = new MySqlConnection(yourConnectionString);
//Execute your queries
cn.close();
This is better since you don't risk leaving open connections, or having transaction issues typing up databases and resources.
With the having just the data returned and not the actual datareader this is a good idea but by just returning the data as an ArrayList or whatever you are kind of losing the structure of the data a little.
A good way to do this would be to either have your class just take the datareader to populate it's data OR have the Data Layer just return an instance of your class after reading the data.
I believe that it would be an excellent approach if your data access class returned a custom class populated with data from the database. That would be object-oriented. Instead of, say, returning a DataSet or an array containing customer information, you would create a Customer class with properties. Then, when you retrieve the data from the database, you populate an instance of the Customer class with the data, and return it to the calling code.
A lot of the newer Microsoft technologies are focusing on making this task easier. Quite often, there are many more than 6 classes needed, and writing all that code can seem like drudgery. I would suggest that, if you are interested in learning about those newer approaches, and possibly adapting them to your own code, you can check out Linq to SQL and Entity Framework.
one question was about if the connection should remain open the whole
time the app is running, or open it fire a query then close it etc
You want to keep the connection open as little as possible. Therefore you should open on each data request and close it as soon as you are done. You should also dispose it but if your database stuff is inside a C# using statement that happens automatically.
As far as the larger question on how to return the data to your application you are on the right track. You typically want to hide the raw database from the rest of your application and mapping the raw data to other intermediate classes is the correct thing to do.
Now, how you do this mapping is a very large topic. Ideally you don't want to create classes that map one to one your tables/columns but rather provide your app a more app-friendly representation of the data (e.g. business objects rather than database tables.) For example, if your employee data is split in to or three tables for normalization purposes you can hide this complexity and present the information as a single Employee class that binds the data from the other tables together.
Abstracting away your data access code using objects is known as Object/Relational mapping. It's actually a much more complex task than it appears at first sight. There are several libraries, even in the framework itself, that already do very well what you're trying to implement.
If your needs are very simple, look into typed DataSets. They let you create the table classes in a designer and also generate objects that will do the loading and saving for you (given certain limitations)
If your needs are less simple, but still pretty simple, I recommend you take a look at Linq To SQL to see if it covers your needs, as it does table-class mapping in a very straightforward way and uses a more modern usage pattern than DataSets.
There are also more complex ORMs that allow you to define more complex mappings, like Entity Framework or nHibernate, but very often their complexity is not necessary.
Details like connection lifetime will then depend on your specific needs. Sometimes it's best to keep the connection open, if you have a lot of queries caused by user interaction, like is usually the case with a desktop app. Other times it's best to keep them as short as possible to avoid congestion, like the case of web apps.
Whichever technology you choose will likely end up guiding you onto a good set of practices for it, and the best you can do is try things out and see which works best for you.

Categories

Resources