I'm researching MongoDB at the moment. It's my understanding that the official C# driver can perform serialization and deserialization of POCOs. What I haven't found information on yet is how a reference between two objects is serialized. [I'm talking about something that would be represented as two seperate documents, with ID links, rather than embeded documents.
Can the serialization mechanism handle this kind of situation? (1):
class Thing {
Guid Id {get; set;}
string Name {get; set;}
Thing RelatedThing {get; set;}
}
Or do we have to sacrifice some OOP, and do something like this? (2) :
class Thing {
Guid Id {get; set;}
string Name {get; set;}
Guid RelatedThing_ID {get; set;}
}
UPDATE:
Just a couple of related questions then...
a) If the serializer is able to handle situation (1). What is an example of how to do this without using embedding?
b) If using embedding, would it be possible to query across all 'Things' regardless of whether they were 'parents' or embedded elements? How would such a query look like?
The C# driver can handle serializing the class containing a reference to another instance of itself (1). However:
As you surmised, it will use embedding to represent this
There must be no circular paths in the object graph or a stack overflow will occur
If you want to store it as separate documents you will have to use your second class (2) and do multiple inserts.
Querying across multiple levels is not really possible when the object is stored as one large document with nested embedding. You might want to look at some alternatives like:
https://docs.mongodb.com/manual/applications/data-models-tree-structures/
Yes, That is completely possible.
One thing you must understand about MongoDB and most NoSQL solutions is that objects can be contained within other objects. In the case of MongoDB, it's basically, if you can create the object in JSON, then you can create the object in MongoDB.
In general, you should strive to have a "relatively" denormalized database structure. A little bit of duplicated data is ok as long as you're not updating it often.
If you really want a reference to another document, you can use a DBRef. However there is limitation with references in MongoDB.
you can only query by id on a ref
when you get your Thing's document, you'll have to make a second query to get the associated RelatingThing's document as join doesn't exists in MongoDB.
I've encountered the same issue recently, and I usually steer away from them but... I'm thinking that this could be a good use for a significant numbering system deployed on the Id field.
class Thing {
string Id {get; set;}
string Name {get; set;}
string RelatedThing {get; set;}}
So, simplifying, if Id was something like "T00001" (or indeed T + GUID), you could easily get the set of things from Mongo by querying for something like Id starts with T, and setting up objects for them all (or just for the subset you know contains your reference, if it is a very large set).
You know/expect that RelatedThing to be a Thing, but it will just be a string when it comes back from Mongo. But if you've set up objects as above, you could effectively use the string as if it were an object reference (after all, that is what it really is, done kind of "manually").
Its a 'loose' way of doing it, but might be workable for you.
Can anyone see any pitfalls with that approach?
Related
I have a service call that accepts the following model:
public class ServiceModel {
public DataModel dModel {get; set;}
public JObject schema {get; set;}
}
The DataModel is responsible for holding data that will be used to populate user defined schema (see below).
The schema is a user defined (at runtime) dynamic json structure that contains tokenized values like this. Being that it's user defined, it can be deeply nested.
{
"id": "<tokenized_id>",
"hero":{
"heroName": "<tokenized_heroName>",
"heroType": "<tokenized_heroType>",
"heroSkill": "<tokenized_heroSkill>",
"heroArmor": {
"armor_id": "<tokenized_armorId>",
...
}
}
}
What I want to do is pull data from the DataModel and replace the corresponding tokenized value with it. The tricky part comes from the possibility of deeply nested objects
My first idea is to just flatten the schema into a string and doing a Find/Replace on the entire string but I'm curious if there's a more elegant way.
There's the option of working with JObjects or even Dictionary but neither provide a nice way to access nested objects. I believe I would need to use recursion which could get ugly.
Are there betters ways to accomplish this?
I need to store a standard record structure in a template file that can be loaded in by a c# program. The record structure relates to a new entry in a database.
Each new entry has:
- a header which has a list of values for that table, and
- a list of items that link to the new entry
Now, here's the tricky part.
- Each item can itself have a list of sub-items (that are all item type)
The program should load in the template, create a new record, and then process each item one at a time. If the item contains a list of sub-items, those will be processed before the parent item is completed.
I was thinking I could perhaps achieve this using JSON?
I will not give you code for doing this but may be enough pointers.
Design the Class that should represent your Record. Ex:
If my record is that of an Employee
public class Employee
{
public string Name {get; set;}
public string EmpId {get; set;}
public Link<Jobs> JobHistory {get; set;}
}
Read about Serializers. Using them you can convert objects to Binary, Xml, Json etc. formats. So this is key for getting the state/stuff that needs to be persisted.
Read about File handling stuff in System.IO. File.Write/Read methods. Also, how to use these along with Serializers (may need to read on MemoryStream/StreamReader/Writers etc). This will help you write the persistable state into file system.
Thanks Prateek Shrivastava,
Lists was the solution I was looking for.
I tried storing the data as JSON, but worked out better to create a few additional tables in the database, and write an app to create and edit templates.
Using JSON.NET for the serialisation and deserialisation.
I can't seem to find an answer for this, even after Googling around.
We are experiencing issues causing our app to lock up. Partly this is because we have outstanding WaitForNonStaleResultsAsOfNow calls that we are waiting to release fixes for (i.e. we have removed them) but also this is being caused by a total rebuild of all indexes. I believe the trigger that causes all indexes to be rebuilt is when we make a change to one (type of) document. For example:
We have a model called "Agency". When our users log in, we use their "AgencyId" in order to provide them with data specific to them. As such, most other documents (such as "Placements", "Invoices" etc) have an "AgencyId" field.
Agency model looks something like:
public class Agency
{
public string Id {get;set;}
public string AgencyName {get;set;}
// ...
}
Example of Placement (and other Agency specific documents)
public class Placement
{
public string Id {get;set;}
public string AgencyId {get;set;} // relates to Agency Document
// ...
}
We have a feature that allows Administrators to upload documents (PDFs) to an Agency's profile. We store the PDF in a DFS and set the "DocumentPath" property on the Agency model to where it's saved.
My question: Would updating the Agency record cause a rebuild of all related documents' indexes? i.e. I know the AgencyIndex would rebuild but would this cause the PlacementIndex (and all other related indexes) to rebuild as well?
More information:
Raven Client Build#: 2.5.2952
Raven Server Build#: 2.5.2952 (RavenHQ)
Also worth noting: We are working on upgrading to RavenDB 3.0 asap but this is a real live problem and I need to understand why it's happening!
Yes, for sure updating a doc the many others points to causes the indexes to rebuild.
Some types of operations needs the index no to be stale (or force update on stale index). It's necessary to pass a deadline to your WaitForNonStaleResultsAsOfNow, that can receive a TimeSpan as param, so you'll wait for the index not to be stale for predefined type.
I'm mapping up data from an SQL database into an object in c#. The problem is, one of the columns is unfortunately named "100_hrs". So when I am making my C# object, I get an error in the declaration:
public float 100_hrs {get; set;}
I've tried using # in front but it does not work. If the property is not named the same as the table column, then it does not map up. How can I map this up?
You can use column attribute as below
[Column("100_hrs")]
public float hundred _hrs {get; set;}
MSDN
MVC3 naming a column beginning with a number
Answering why the # didn't work.
# lets you declare variables with keywords names, it doesn't allow you to use invalid tokens.
MSDN
Regarding to the main question, it seems like you should change the table column name.
If you're using some sort of mapping engine like NHibernate of EntityFramework, you can change the mapping file. Example:
[Column("100_hrs")]
public float hrs100 {get; set;}
Why not use underscore before the number say _100_hrs since you could easily manipulate it by string extraction if you want to map it to your column? Although there is a little overhead it sure solve your problem.
This question arose when I was trying to figure out a larger problem that, for simplicity sake, I'm omitting.
I have to represent a certain data structure in C#. Its a protocol that will be used to communicate with an external system. As such, it has a sequence of strings with predefined lengths and integer (or other, more complicated data). Let's assume:
SYSTEM : four chars
APPLICATION : eight chars
ID : four-byte integer
Now, my preferred way to represent this would be using strings, so
class Message
{
string System {get; set; }; // four characters only!
string Application {get; set; }; // eight chars
int Id {get; set; };
}
Problem is: I have to ensure that string doesn't have more than the predefined length. Furthermore, this header will actually have tenths of fields, are those will change every now and then (we are still deciding the message layout).
How is the best way to describe such structure? I thought, for example, to use a XML with the data description and use reflection in order to create a class that adheres to the implementation (since I need to access it programatically).
And, like I said, there is more trouble. I have other types of data types that limits the number of characters/digits...
For starters: the whole length issue. That's easily solved by not using auto-properties, but instead declaring your own field and writing the property the "old-fashioned" way. You can then validate your requirement in the setter, and throw an exception or discard the new value if it's invalid.
For the changing structure: If it's not possible to just go in and alter the class, you could write a solution which uses a Dictionary (well, perhaps one per data type you want to store) to associate a name with a value. Add a file of some sort (perhaps XML) which describes the fields allowed, their type, and validation requirements.
However, if it's just changing because you haven't decided on a final structure yet, I would probably prefer just changing the class - if you don't need that sort of dynamic structure when you deploy your application, it seems like a waste of time, since you'll probably end up spending more time writing the dynamic stuff than you would altering the class.