How to control JSON.NET serialization of System.Data.Spatial.DbGeometry - entity-framework

I have a DB First Entity Framework 5 Data Access Layer that is mapped to a table containing a SQL geometry type field called CenterCoordinate. The resulting entity contains this:
public System.Data.Spatial.DbGeometry CenterCoordinate { get; set; }
My client javascript requests the API and only accepts JSON. I then use the Asp.net Web API to serve this using the default formatter (JSON.NET). In the API controller the field has a long list of properties including an XCoordinate and a YCoordinate.
In the client the JSON only contains this:
Geometry: Object
CoordinateSystemId: 3498
WellKnownBinary: null
WellKnownText: "POINT (6438089.715 1801515.828)"
I really don't want to have to parse out the WellKnownText to get to the values of X and Y.
So the question is how can I control the serialisation/de-serialisation of System.Data.Spatial types to/from JSON such that I get something more useful? How does the JSON.net formatter know what to include/exclude?
Note: I really don't want decorate the entity with attributes as these will be lost each time I regenerate the model from the database (I have no idea why we can't add attributes to model fields through VS2012 and have it remember them after a regeneration). So can this be with partial classes or overriding the formatter?
Thanks, Matt

Unfortunately, you're more or less stuck parsing the WellKnownText field if you want to manipulate the coordinates with Javascript.
Geometry is a SQLSpatial type that is saved to a database via the WKT field, so that's why your DbGeometry type is converting the JSON to that format.
If it makes you feel any better, it's causing me just as much of a hassle right now.
Edit: These resources might help a bit:
GeoJSON has a structure much more similar to SpatialSQL:
http://www.geojson.org/geojson-spec.html
https://github.com/Esri/geojson-utils/blob/master/src/jsonConverters.js
This is a solution used to serialize/deserialize DbGeo types as JSON:
http://www.arcgis.com/home/item.html?id=6d28a606369c43fd9a6f929541ae7c93

Related

How to use Entity, Mapper, Service and Hydrator in ZF2

I am making a ZF2 app. I am using entities, mappers and services (e.g. UserEntity, UserMapper, UserService) to manage the objects/models. Properties in the entities are CamalCased (e.g. FirstName, LastName) while in the database, fields are using underscore (first_name, last_name). I will plan to use a hydrator to map the properties and db-fields when retrieving or saving. The service object (UserService) will be used to communicate with the mapper to retrieve and save data models using the mapper. The hydrator will convert the result of mapper and convert them into proper entities.
The thing I am confused is that when the service (UserService) need to provide some cirteria - for example to find all users with a specific 'last name', will the service use the database field names (last_name) or entity properties name (LastName)?
If the db field name is used in the Service, so any change in the db structure will require me to update the service also, which completely fails the reason of using the whole approach.
If you take a look at the ClassMethods:hydrate method (https://github.com/zendframework/zf2/blob/master/library/Zend/Stdlib/Hydrator/ClassMethods.php) you will see that it just copies the properties from one object to another. You have the option of converting the property names to/from camelCase but that's it.
If you change a column name in your database then you will need to change corresponding property name in your object. And vice versa. Which I believe is the crux of your question?
If you want to make table column names be independent of your method names then you need something that lets you define an actual mapping table somewhere. Change a column or method name and you only need to update the configuration mapping table.
Not a ZF2 expert so I could be wrong but it doesn't look like any of the supplied hydrators support this.
I do know that Doctrine 2 supports it.

Is there a way to map a Date column to a string property in EF?

I know I can solve this by adding another property to my entity which will contain the conversion between types but was wondering if it is possible with EF CF.
Do you need this for UI presentation (of the DateTime value) reasons?
If so, you might want to consider defining a separate View model class, and using something like AutoMapper to map the properties between the two.

How to tell entity framework how to save instances of a custom type (that can be stored as a scalar)

One of my entity classes would be possible to store in a sql server
database as a BIGINT. My question is: How do I get a Entity Framework
context to know how to store and retrieve instances of my entity class?
More detail. I'm using Noda Time, which can represent a (much) wider range of
dates than can SQL or .NET datetime (AND it's a dessert topping). My Entity Class, Happening, is a wrapper around NodaTime's
Instant class. I can set a Happening from a long, and get a long from
a happening with methods like .SetFromLong(long instant) and .ToLong().
Currently I have my model working, saving classes that contain
properties of the dot net DateTime type. If instead I want to use properties
of my custom type "Happening", how do I tell Entity Framework how to save those?
If I'm reading this article about Modeling and Mapping am I on the
right track or missing something simpler?
http://msdn.microsoft.com/en-us/library/bb896343.aspx
I'm using entity framework 4.
What i recommend doing is adding 2 properties on your entity a NodaTime and a long, and exclude your NodaTime property using [NotMapped] in your EF model, then in your getter/setter update the long.
ie
public class MyEntity{
public long TimeAsLong{get;set;}
[NotMapped]
public Happening {
get{
return new Happening().SetFromLong(TimeAsLong);
}
set {
TimeAsLong = value.ToLong();
}
}
}
The effect of this will be that the long is stored in the db but you can access it on the class via NodaTime

Entity framework 4 model first using money value object

I want to use a Money value object in my application. I have found several examples of a Money datatype. But I can't figure out how to use them with EF4. I would like to store each amount as a Decimal/CurrencyCode pair (where currencycode is a string - "USD", "SEK", etc) in the database. I tried creating a complexType but I couldn't get that to work. Is this possible?
It should be definitely possible. Your complex type is just pair of decimal and string property. It is exactly what complex type are used for. Depending on your approach you must do:
Database first:
You will define your database first. Your table will contain money and varchar columns representing your new type. When you update your EDMX model from database it will include it as scalar properties to your entity. You must remove those properties. Then go to model browser and create new complex type. Return back to entity and add complex property of your new complex type. And at the end you must go to entity mapping and map your complex type to those database columns.
Here is basic tutorial from MSDN but from unknown reason they didn't include such elementary details like screenshots. Here is some video from channel9.
Model first:
This is similar to database first but you don't have to deal with database creation and mapping. It will be generated for you.
Code first (EF 4.1):
You must create separate class for your complex type and use it as property in your entity. You should not need to map it by default - mapping should be infered. If it doesn't work you can map complext type either by using ComplextTypeAttribute annotation or by defining mapping in DbModelBuilder.
I can further extend approach you need to use if you provide more details.

iPhone core data migration date to string

I have an entity that originally started with a date attribute. I have now added a attribute that is a string that I want to hold the date, in addition to keeping the original field.
I've made a mapping model, but I'm not sure what to put into "value expression" to get the new string field filled with data from the date field in the format "2010-10-25" during migration.
Any help would be appreciated.
Also I need it to be a real attribute not a transient because I want to sort on it. I didn't realize you couldn't sort on transient attribute until too late.
Translating the property from a date to a string is going to require that you build your own NSEntityMigrationPolicy for that migration and override the -createDestinationInstancesForSourceInstance: entityMapping: manager: error: method to handle the translation.
This should be very straight forward code since you are only going to be manipulating a couple of properties and the entity mapping is still one to one.