Custom persistor

Dec 4, 2011 at 5:58 PM

Hi,

What would be the approach for creating a custom persistor?

The scenario I am thinking of is the following: I have some custom value types (with their corresponding semantics) that Entity Framework can't handle out of the box, so I would have to access the DbContext and override OnModelCreating to add custom mapping rules. Can I achieve this by extending the Entity Persistor or do I have to create a new one?

Also, what is the purpose of Inline attribute. Is it expected to not work if using the In-Memory Persistor? (i.e. getting some null reference exception when creating a new transient entity that has properties of custom value types marked as inline)

Thank you!

-Adi

Coordinator
Dec 5, 2011 at 8:16 AM

I can see no reason why you shouldn't just extend the existing entity persistor. Writing a completely new persistor is more a matter of using a different persistence mechanism eg NHibernate.

I assume you've looked at the way in which the EF fluent configuration is exposed through the EntityPersitorInstaller and that it doesn't do what you want. It would be useful if you could create a detailed issue with your requirements and then we can look into exposing the functionality you want in a generic way. 

However depending upon what you want to do you may also like to take a look at the framework mechanism for custom value types. There are some examples in the NakedObjects.Helpers projects eg the Image class.

The inline attribute, when using EF, indicates a complex type. However it should still work when using the in-memory persistor. There it just indicates that the value should be edited inline and has no seperate identity. If you're mixing transients, custom value types and inlines you're getting to the point where you need to be looking at the code and understanding where values are coming from over each web transaction (eg hidden fields on forms or perhaps you need to use 'StoreTransientsInSession').

 

 

Dec 27, 2011 at 11:33 PM

Thank you for your reply!

I looked at the built-in value types examples, but I can't figure out how the value semantics providers determine (if at all) the persistence.

Say I have a class called Complex to represent complex numbers:

public class Complex
{
     public float Re { get; set; }
     public float Im { get; set; }
}

and I want to persist instances on one column, as stings (varchar), using the following format: Re|Im

new Complex() { Re = -1.2, Im = 5.1 } => -1.2|5.1

This is just a dummy example, of course. I'm sure there are better ways to represent complex numbers in a database, but I'm hoping this gives you an idea of what I am trying to achieve.

Thank you!

Coordinator
Dec 28, 2011 at 9:26 AM

Take a look at the Money class, defined in NakedObjects.Helpers, which, like your complex number example, has two elements -  a monetary value and a currency. 

The corresponding MoneyValueSemanticsProvider in NakedObjects.Reflector.DotNet defines methods: DoEncode and DoRestore, which convert this type into a string and back for persistence.  (Also a DoParse method for parsing text input.)

FYI, we are aware that the need to define a separate semantics provider from the class itself is rather ugly.  A long term goal is to design a rather cleaner model for this.  However, it is not high priority because not many of our users have added their own value types. 

Bear in mind that another option for you may be simply to treat your custom value types as complex types (from entity framework's perspective).  For an example of this look at the TimePeriod class in the AdventureWorks sample application.  TimePeriod is a value type from Naked Objects' perspective (meaning that it can be entered and displayed as a single text field despite having multiple properties), and therefore has a TimePeriodValueSemanticsProvider to handle the display and parsing.  But from the EF perspective it knows nothing about a TimePeriod type  -  it merely handles the From and To dates as a complex type.  This is clearer in the code than in my explanation, probably!