Map old field name and new field name from mongodb document to the same c# field - mongodb-.net-driver

Does the MongoDB C# driver have the ability to map two field names from the server to a single field in the C# class?
The reason that we need this is that we've renamed a field in our code and would like to support both the old and new field name for a period of time.
This is a typical data migration scenario and it would be very helpful if we could establish a pattern for doing this via mapping without having to add special version logic to the data entity class or to the logic code.
We're currently using the official c# driver v2.3 with server v3.2.

I don't think that is very much possible. What you can do is
Create a new property that is not saved in the bson. Use BsonIgnore tag thusly and populate the data from both of your property and expose that in the JSON response you are providing. Use JsonIgnore to make sure you provide proper ignoring directives there.
Go for migration techiniques in Mongodb. You can use a migration tool like this one. As you are using the C# driver 2.3.0 I would presume you want to use that and you can use my fork here for C# driver 2.3.0 compatibility.
Code sample for number 1:
class Data
{
[JsonIgnore]
public string OldProperty { get; set; }
public string NewProperty
{
get
{
// Return this one or the old one based on your logic
}
set;
}
}

Related

Petapoco missing attributes IgnoreOnInsert, IgnoreOnUpdate

I'm trying to use Petapoco in my Umbraco powered website. On my poco's I have a column called Created which has a default sql value (getDate()). I would like that column to be ignored on insert and update by Petapoco, but not on read.
Any idea how can I achieve that elegantly? perhaps with a custom mapper or including some new attributes in Petapoco engine (like IgnoreOnInsert, IgnoreOnUpdate).
I've been using some hacks, one of them was having two poco's for each table, one for insert-update and one for reading. But it's difficult to accept that as satisfactory.
I usually just make a class constructor and set the date property there. Something like
public class WhatEvs
{
...
public WhatEvs()
{
DateCreated = DateTime.Now;
}
}
In case anyone is still interested in this, I eventually found a nice solution.
And that is to stop using Petapoco and switch to NPoco, which has a nice attribute called 'ComputedColumn'.
If you decorate a property with [ComputedColumn] attribute, that property will not be used when NPoco generates insert and update queries, but it will be used in select queries.
That allows me to nicely have database handled values like CreatedDate or UniqueGuid which I don't touch, but am able to get when querying.
Thanks to Aaron who kindly answered this problem here:
https://github.com/CollaboratingPlatypus/PetaPoco/issues/421#issuecomment-348390149

Store data "inside" app without storing it in databases

I have the following situation: I have some models in which I deserealize data from XML (which was received by GET request). Then i want to use these objects everywhere in app. How to store them? I don't want to store this data in local databases.
P.S. I use MVVM
Here are your options as I see it:
If you need it to persist when the app is closed
Sqlite and store it locall. Sqlite isn't that scary if that's what you're worried about. Here's a good blog post on how to handle it in a really easy way: Super Simple Sqlite
Write to a file like #Jason suggested.
Use a key-value storage like #apineda suggested.
For all of these, you can use them WITH what I explain below.
If you do not need it to persist
Create a Store that has a property for your collection of data. Then access that Store class from your ViewModels or another Service layer or whatever you like. This can be combined with any of the above mentioned long-term storage strategies. If you need your Store to persist, consider using Dependency Injection to inject it into your ViewModels that require it, or store it as a reference in your App if you're using Xamarin.Forms or some Singleton.
Here's an example:
public class ItemStore
{
public List<Item> DataItems { get; set; }
}
Then set a store property in your App.cs:
public class App : Application
{
...
public ItemStore ItemStore { get; set; }
...
}
Then reference it from your ViewModel:
((App)App.Current).ItemStore.DataItems = yourParsedCollection;
And you can get it in the same way.
You can save your data in a file and load from here every time you want . It's really fast if a data is only one xml file.
Take a look Saving and Loading Files
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/files/

What does Spring Data Couchbase use the _class field for?

I'm guessing that the type is used for CRUD operations. Is it used for anything else besides that? I'm wondering what impact there could be from configuring how it gets populated.
The _class field is written to allow polymorphic properties in your domain model. See this sample:
class Wrapper {
Object inner;
}
Wrapper wrapper = new Wrapper();
wrapper.inner = new Foo();
couchbaseOperations.save(wrapper);
You see how the field inner will get Foo serialized and persisted. On the reading side of things we now have to find out which type to create an object of and the type information in Wrapper is not enough to do so as it only states Object.
That's why Spring Data object mapping persists an additional field (name customizable but defaulting to _class) to store that information to be able to inspect the source document, derive a type from the value written for that field and eventually map that document back to that particular type.
The Spring Data Couchbase reference documentation doesn't really document it, you can find information about the way this works in the docs for the MongoDB module. I've also created a ticket for Spring Data Couchbase to improve on the docs for that.

Why my super simple ASP.NET Web API (mvc4)+Entity Framework 5 doesn't work?

I spent days to know the problems of my work, but no luck.
I created new MVC4 Web API project.
Add EF5 with my database (Project>Add>ADO.NET Entity Data Model>Create from database which is in Azure SQL).
Add two tables to edmx as below. And two *.tt files generate entities and model classes successfully.
I can see the breakpoint(result) gives query result normally.
But json gives abnormal stream without error message. (ie, http://localhost:41813/api/sheet/157 returns "157" which cannot download. in general, "157.json" is downloaded)
I copied properties in results to my handmade POCO-style class and it works.
What is my problem? I cannot use generated model classes to send data through Json.
I hardly find out problem because no error message and no debug step available after the result breakpoint.
The reason the serialization fails are yours Navigation Properties - while the serializer is trying to walk the object graph they result in circular dependencies.
For your simple sample to work you have few ways around it.
Remove Navigation Property Sheet from SheetDetail
Wrap your objects in ViewModel classes with Navigation Property Sheet omitted
Create a metadata class with JsonIgnoreAttribute and then attach it to your entity with partial class and MetadataTypeAttribute
Here you can find sample for third solution (sample makes some assumptions as I don't know your exact data types):
public class SheetDetailSerializationMetadata
{
[JsonIgnore]
public Sheet Sheet { get; set; }
}
[MetadataType(typeof(SheetDetailSerializationMetadata))]
public partial class SheetDetail
{
}
As #danludwig comment, http://www.asp.net/web-api/overview/formats-and-model-binding/json-and-xml-serialization gives all answers about my problem.
Add below code in Global.asax solves the problem.
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling =
Newtonsoft.Json.PreserveReferencesHandling.All;

Protobuf, how to add custom version detail in binary

I want to tag each protobuf serialized data with my own version number. so i can check which version was used to serialize data if required. Although protobuf is designed around idea so you don't need to check version.
To do that i can use same way we have been doing in .net serialization add version field in it.
Just want to confirm that this is the preferred way of doing in protobuf as well.
class protodata1
{
public protodata1()
{
version = 1;
}
[Protomember(1)]
int version { get; set;}
[Protomember(2)]
int somedata { get; set;}
}
Also should be done like above in protobuf-net?
assign version in constructor which will get override if class is getting desiralized. for new objects to be serialized it will use version 1
Well, if your meaning of "version" is simply as a data-field, then sure; just add it as a serialized member. Note that this won't have any special meaning during serialization (running it through an alternative contract, for example) - although as an aside there might be options here in "v2" if you need to support radically different message structures (a bad idea anyway).
The only caveat I might add is that any existing data that didn't already include this number will claim to be "version 1". In "v2" another option is to use the WCF approach of skipping the constructor (if you require). This will mean that these cases default instead to "version 0" - perhaps less confusing (or perhaps more confusing; I'll let you decide).

Resources