How to store information offline. C#, Unity - c#

I'm working on an application in unity that solves chemical problems. I need to store information about each chemical element offline. For example: hydrogen [mass 1, group 1...], oxygen[mass 16, group 6...] and so on. What do I need to use?

The probably simplest solution would be to use a serialization library, like json .net, these can convert your objects to a serialized stream that can be saved to file. Attributes can typically be used to control how the object will be serialized.
The other major option is to use a database, either a stand-alone database like postgres, or a in-process database like sqlite. The later makes things like deployment easier, but introduces some limitations, like not supporting multiple concurrent applications. In either case you would typically use an "Object Relational Mapper" (ORM), like Entity Framework. This is able to convert your objects directly to database tables.
Files are typically simpler to use, and suitable if you want to store few,larger blobs of data that rarely change. Databases are more suitable if you have many more smaller objects that you want to search among, or when persisting data more frequently.
Note that this is general advice, Unity might have some built in persistence that might or might not be suitable for your particular case.

ScriptableObjects are a great fit for this situation:
[CreateAssetMenu]
public class Element : ScriptableObject
{
[SerializeField]
private int mass;
[SerializeField]
private int group;
public int Mass => mass;
public int Group => group;
}
You can create an asset to hold information about each element.

Create scriptable object:
Add it from menu:
Set Desired data to element:

Related

What C# datatype should be used for a partially constant set of information?

I'm writing a C# application that does some things with baseball statistics. I'm getting the data from an XML web service. I want to completely separate the presentation-business-data layers. In that vain I have created a service class to interact with the web service and to create objects from the data, a set of business classes (i.e. player, team, league), and the objects needed for my presentation layer.
I don't want to load the statistics into the player class because there are more than 200 statistics, and I'm not going to need them every time I instantiate the player class. For each statistic I need its abbreviation, description, XML attribute name, and value.
Question: What C# data-structures or method could be used to present more than two properties and allow several of them to be static across all instances of the datatype and allow at least one to be writable at run-time?
I started to create a "statistic" class like this:
public class BaseballStatistic
{
public string Abbreviation;
public string Description;
public string XmlAttributeName;
public string Value;
public BaseballStatistic(string abbreviation, string description, string xmlAttributeName)
{
Abbreviation = abbreviation;
Description = description;
XmlAttributeName = xmlAttributeName;
}
}
The problem with this is that I'll never need to change the abbreviation, description, or XML attribute name at run-time.
If I only needed the abbreviation and value, I'd use a Dictionary or some other Key/Value pair.
I started to create a statistic class with abbreviation, description, XML attribute name, and value members. But the only one of those that will ever change at runtime is the value - so this didn't feel like the right answer. (Imagine 500 players, each with an array of statistic objects, and those object are the exact same for all players except for the value.)
I considered creating a multidimensional array, but with so many constant values, it seems wasteful to load such a thing at run time.
I feel like I should know this.
I should add this: because there are so many different statistics that I can use, it would be great if I could find a solution that would expose them to Intellisense. For example:
Statistic g = Stats.GamesPlayed
It sounds like you need one class for "a statistic" - and then a Dictionary<PlayerStat, int> (or whatever the value would be).
The PlayerStat class would know about the abbreviation, description and XML attribute name - and I'd suggest that you probably create a Dictionary<string, PlayerStat> statically to map from abbreviation to statistic, and another one to map from XML attribute to abbreviation.
You may not even need the Dictionary<PlayerStat, int> in your Player class... you could always add an indexer or method which looked things up lazily. (Be careful with this, however - you may find that loading many things lazily will be more expensive than loading everything in one go. You may want to break the statistics into categories, and load all the stats for a single category when you load one of them. Basically, if there are clumps of stats that are usually used together...)

Adding side notes to each property in MongoDB document

I have a collection with a collection of documents. Each document has around 20 different properties with different data types (e.g. Int, Double, String).
I am searching for an efficient way or the appropriate way to add side notes to each property.
My thought (I am using C# to model the document structure) is for each property, instead of
:
public int PageRank {get; set; }
to use:
public Dictionary<int, string> PageRank {get; set;}
This means that each item in the document is a collection of both the value and the string for the side note.
The side notes will be seen at the front-end by the user.
Any better implementation?
Idan, for performance reasons, you should consider your use case from the MongoDB point of view -- not from the object oriented language point of view. The way it ends up looking in C# is an afterthought -- its the DB performance that counts. So, when querying your documents, if the side notes are mostly not needed, it will be better to place them into a separate collection (possibly) thus reducing the size of each document and enabling MongoDB to read more of them into the available memory. If the user does need to look at the side notes, you would do this with a separate query. You know your usage scenario better, so its up to you to decide how to do this, but its these kinds of design decisions that you need to concern yourself with -- and the C# code will be shaped according to your schema

Need some advice for project

I'm going to do a project task as the last part of a programming course in C#, and I have choosen to do a media library for storing information of DVD movie collections. The thing I need some advice is about how to save this information since the task should be solved by using simple text files and not databases which had been better.
So, which is the best way to save this information to be able to add, edit and allow search for titles and actors and also sort after genre to mention some of the idéas I have for this program.
Should I just save the information by just add the title, year, playtime, director, actor1, actor2, actor3, genre, grade, comment for each movie lika a row at the end of the file? Can I search in the file or should I, in some way, first read it all into an array, and then do the serach and perhaps edit and save the complete file again?
Or is it better to use XML like this:
<movie_collections>
<movie>
<title=Tron Legacy"></title>
<year=2010></year>
<playtime=120></playtime>
etc.
</movie>
</movie_collections>
If I use XML, can I search for a title and just load or edit that part? Are there better alternatives than these?
You may store the data in XML file. An XML file can store data similar to a database table. You can add multiple records, hierarchical data etc... You may easily query the data using LINQ to XML.
If you dont want to use LINQ to XML, You can use so typical XMLDocument to handle the XML data.
Maybe you're approaching this at too low a level. The file is realistically just for persistance rather than implement your own DB as a file.
Just implement the object that you're after and serialize it out imo.
public class MovieCollections
{
private ICollection<Movie> Movies {get; set;}
// etc...
}
public class Movie
{
public string Title {get; private set;}
public int PlayTime {get; private set;}
public DateTime ReleaseDate {get; private set;}
}
Serialize instance of MovieCollections.
Keep MovieCollections perhaps as a Singleton instance since you only want one collection.
By the way this seems to be very general question & a quite common homework question too!!
I think you should google for this, you will get better projects ideas.
Something similar on this lines :
1.Simple Movie Database in C# using Microsoft Access
2. Create a Movie Database Application
3. imdbapi
& finally
4. SO's similar post
And as far as comparison between a database & XML is concern, I did recommend you a database because several pros over XML as far such type of project is considered.
As #M_Affifi suggests, think of all your interaction with your data (e.g. sort, add, find, delete, update, etc) through your objects which reside in memory (e.g. Instance of MovieCollections class and instances of Movie class), the XML file is only used to store the state of your objects, so you have that data available next time you run your application.
Once you're done manipulating your data just serialize it to XML. Serialization is just the process to convert your objects into a format that you can store or transfer, in this case will be conversion to XML. Take a look at this reference, Your serialization needs are very basic, so you'll need just few lines of code.
System.Xml.Serialization.XmlSerializer x = new System.Xml.Serialization.XmlSerializer(YourObject.GetType());
x.Serialize(Console.Out, YourObject)
Finally, I would suggest thinking of your application logic. When program starts you may want to check if your Movies.xml exists, if so, then 'Deserialize' it, which means loading it from XML to your object collection. If XML file doesn't exist then just start manipulating your objects and when you're done give the option to Save(Serialize). I can help with the serialization/deserialization process if needed.
Hope this is helpful
;

MongoDb and self referencing objects

I am just starting to learn about mongo db and was wondering if I am doing something wrong....I have two objects:
public class Part
{
public Guid Id;
public ILIst<Materials> Materials;
}
public class Material
{
public Guid MaterialId;
public Material ParentMaterial;
public IList<Material> ChildMaterials;
public string Name;
}
When I try to save this particular object graph I receive a stack overflow error because of the circular reference. My question is, is there a way around this? In WCF I am able to add the "IsReference" attribute on the datacontract to true and it serializes just fine.
What driver are you using?
In NoRM you can create a DbReference like so
public DbReference<Material> ParentMaterial;
Mongodb-csharp does not offer strongly typed DbReferences, but you can still use them.
public DBRef ParentMaterial;
You can follow the reference with Database.FollowReference(ParentMaterial).
Just for future reference, things like references between objects which are not embedded within a sub-document structure, are handled extremely well by a NoSQL ODB, which is generally designed to deal with transparent relations in arbitrarity complex object models.
If you are familiar with Hibernate, imagine that without any mapping file AT ALL and orders of magnitude faster performance because there is no runtime JOIN behind the scenes, all relations are resolved with the speed of a b-tree lookup.
Here is a video from Versant (disclosure - I work for them), so you can see how it works.
This is a little boring in the beginning, but shows every single step to take a Java application and make it persistent in an ODB... then make it fault tolerant, distributed, do some parallel queries, optimize cache load, etc...
If you want to skip to the cool part, jump about 20 minutes in and you will avoid the building of the application and just see the how easy it is to dynamically evolve schema, add distribution and fault tolerance to any existing application ):
If you want to store object graphs with relationships between them requiring multiple 'joins' to get to the answer you are probably better off with a SQL-style database. The document-centric approach of MongoDB and others would probably structure this rather differently.
Take a look at MongoDB nested sets which suggests some ways to represent data like this.
I was able to accomplish exactly what I needed by using a modified driver from NoRM mongodb.

design using a readonly class in c#

Small design question here. I'm trying to develop a calculation app in C#. I have a class, let's call it InputRecord, which holds 100s of fields (multi dimensional arrays) This InputRecordclass will be used in a number of CalculationEngines. Each CalculcationEngine can make changes to a number of fields in the InputRecord. These changes are steps needed for it's calculation.
Now I don't want the local changes made to the InputRecord to be used in other CalculcationEngine's classes.
The first solution that comes to mind is using a struct: these are value types. However I'd like to use inheritance: each CalculationEngine needs a few fields only relevant to that engine: it's has it's own InputRecord, based on BaseInputRecord.
Can anyone point me to a design that will help me accomplish this?
If you really have a lot of data, using structs or common cloning techniques may not be very space-efficient (e.g. it would use much memory).
Sounds like a design where you need to have a "master store" and a "diff store", just analogous to a RDBMS you have data files and transactions.
Basically, you need to keep a list of the changes performed per calculation engine, and use the master values for items which aren't affected by any changes.
The elegant solution would be to not change the inputrecord. That would allow sharing (and parallel processing).
If that is not an option you will have to Clone the data. Give each derived class a constructor that takes the base Input as a parameter.
You can declare a Clone() method on your BaseInputRecord, then pass a copy to each CalculationEngine.

Categories