Hi,

We're almost done with our research of ORM's. There are 2 candidates of the initial 22 remaining (DO4 and NHibernate). We have one question open for DO4, here it is:

We use T4 Generation in VS2010 for generating code for our Model and ViewModel. The current scripts rely on the EF's edmx file (we're moving away from EF). The scripts have need for MetaData about the conceptual model (entities, (navigation-)properties, property attributes, etc). Does DO4 expose this kind of information?

Regards Paul Sinnema Diartis AG


Updated at 31.05.2010 14:20:16

Hi Alex,

Thanks for the reply. This would mean that we can only generate our partial classes for our Model after the Model has been compiled. Looks a bit like the chicken and egg problem. We need the Model to generate classes, to be able to compile the classes we need the generated classes. How can we overcome this paradox?

Regards Paul Sinnema Diartis AG


Updated at 01.06.2010 6:48:53

I think you should "parse" EDMX file(s), extract informations about model from there, and generate new model code for DO4 (e.g. by T4 templates). for parsing EDMX files, see: http://www.codeproject.com/KB/library/EdmxParsing.aspx

Yep, that is a solution, but it is not a very nice one. We strive to completely remove the EF from our project. That way the .edmx would still be part of the project. If all nice solutions fail, we'll have to look at less nice ones too.

Thanks anyway. Paul.


Updated at 01.06.2010 6:51:50

> This would mean that we can only generate our partial classes for our Model after the Model has been compiled. You didn't say you plan to modify it ;) Actually, there is IModule type allowing to modify DO4 model before Domain startup, but this is a bit tricky: - You must implement IModule in one of types you register - And implement OnDefinitionsBuild method there - Model definition (preliminary, lightweight model) is passed as argument of this method, so you can modify it there - See *Def classes inside Xtensive.Storage.Building.Definitions to add types and properties you need. Note that you anyway must provide real types there, but fields might not be declared inside them (you'll access them via entity["Field"] syntax).

Alex,

I think you misunderstood me. Ok, let me tell you what we did with the EF.

  1. We define the model in the .edmx file
  2. With the validated conceptual model we generate partial classes for the model
  3. We compile the project.

This way we can generate 'standard' extra code for classes in the model.

The difference with DO4 and EF is that DO4 exposes the MetaData after and the EF before compilation. The moment the scripts run for the partial classes the metatdata has to be present.

In the partial classes only members that are not in the DB are generated, meaning in the case of DO4 that we will not generate members that have the [Field] attribute.

Regards Paul


Updated at 01.06.2010 10:08:59

Yes, DO4 exposes the whole available info in read-only mode after building the Domain: - Domain.Model property exposes primary model used by DataObjects.Net providing info about types, fields, keys, associations, indexes and so on. See Xtensive.Storage.Model namespace for complete info about it. - Domain.Schema and Domain.ExtractedSchema provide info about schema only. These models aren't "connected" with types directly (i.e. there are no direct refs to types, fields, etc.), they're used only for schema comparisons and upgrades. In fact, schema is result of translation of Domain.Model to unified schema model. So if Domain.Model is storage-independent, Domain.Schema depends on features supported by a prticular storage. See Xtensive.Storage.Indexing.Model namespace for complete info about it. There is also SQL DOM schema model used internally by SQL-based storage providers in DO4, but most likely, you won't need it. P.S. I noticed that by some reason Domain members aren't shown in documentation (likely, it's either a Sandcastle or Help Server issue -we will check this on Monday). So currently I can only recommend to look up its source code (it's relatively small), if you're interested what other useful members are there.

Alex,

I guess i've been too much stuck in our old situation. What I completely discarded is the fact that with DO4 we are able to inherit from the Model classes (which was impossible in our previous scenario). This means that we can have a Model Assembly separate from our generated Model Classes instead of using partial classes in the same assembly. So, I guess we can generate our classes easily after the Model Assembly has been compiled and have our T4 scripts kick in on the start of the 'build' of the second assembly.

Having said that, another question pops up. Can we enrich the Model with our own Custom Attributes and find those in the MetaData of DO4? We would need attributes on fields, for instance telling us if a certain datefield is a 'datefrom', 'dateto' or single date (i.e. BirthDate).

Regards Paul


Updated at 08.06.2010 13:36:42

Hi,

We've started building a module which uses VS2010 symbols to itterate all the classes and members of our conceptual model (being C# Classes with our own Attributes). We will generate the DO4 Classes using these Attributes in the conceptual model (i.e. [Field(, Key)], [Association .....], etc), alongside Attributes we need to complete our own classes (ViewModel).

All code is generated using T4 and bases on the Modul mentioned above. This means we will not be using the MetaData in DO4 at all and will completely rely on our own MetaData to generate the DO4 Classes, ViewModel and several other helper classes.

Tell me what you think of this approach.

Regards Paul Sinnema Diartis AG

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked May 29 '10 at 13:45

Paul%20Sinnema's gravatar image

Paul Sinnema
261888896


One Answer:

Alex (Xtensive) wrote:

Yes, DO4 exposes the whole available info in read-only mode after building the Domain:

  • Domain.Model property exposes primary model used by DataObjects.Net providing info about types, fields, keys, associations, indexes and so on. See Xtensive.Storage.Model namespace for complete info about it.

  • Domain.Schema and Domain.ExtractedSchema provide info about schema only. These models aren't "connected" with types directly (i.e. there are no direct refs to types, fields, etc.), they're used only for schema comparisons and upgrades. In fact, schema is result of translation of Domain.Model to unified schema model. So if Domain.Model is storage-independent, Domain.Schema depends on features supported by a prticular storage. See Xtensive.Storage.Indexing.Model namespace for complete info about it.

There is also SQL DOM schema model used internally by SQL-based storage providers in DO4, but most likely, you won't need it.

P.S. I noticed that by some reason Domain members aren't shown in documentation (likely, it's either a Sandcastle or Help Server issue -we will check this on Monday). So currently I can only recommend to look up its source code (it's relatively small), if you're interested what other useful members are there.


psulek wrote:

I think you should "parse" EDMX file(s), extract informations about model from there, and generate new model code for DO4 (e.g. by T4 templates).

for parsing EDMX files, see: http://www.codeproject.com/KB/library/EdmxParsing.aspx


Alex (Xtensive) wrote:

> This would mean that we can only generate our partial classes for our Model after the Model has been compiled.

You didn't say you plan to modify it ;)

Actually, there is IModule type allowing to modify DO4 model before Domain startup, but this is a bit tricky:

  • You must implement IModule in one of types you register

  • And implement OnDefinitionsBuild method there

  • Model definition (preliminary, lightweight model) is passed as argument of this method, so you can modify it there

  • See *Def classes inside Xtensive.Storage.Building.Definitions to add types and properties you need. Note that you anyway must provide real types there, but fields might not be declared inside them (you'll access them via entity["Field"] syntax).


Alex (Xtensive) wrote:

> Can we enrich the Model with our own Custom Attributes and find those in the MetaData of DO4? We would need attributes on fields, for instance telling us if a certain datefield is a 'datefrom', 'dateto' or single date (i.e. BirthDate).

DO4 doesn't offer anything to help you here, but as far as I can judge, this isn't necessary in your case:

  • DO4 models are designed to serve for its own purposes: they provide info related to persistence, mapping, associations, validation, etc., and they do this fast.

  • Your own model extensions must provide info for your own purposes - i.e. DO4 won't use this info.

Since cases are different, keeping different models here is probably not a bad idea at all. Although, if you like to, you can implement e.g. extension methods to our TypeInfo and FieldInfo exposing members from your model.

Few important points:

  • Both Domain and Session type implements IHasExtensions interface. This interface enables you to bind generally any custom information with these objects. Ideally you should use some internal type as key there, e.g. CustomModelRoot.

  • Note that up to 3 Domains are built during upgrade, so IModule.OnDefinitionsBuilt might be invoked up to 3 times (for different upgrade stages).

answered May 29 '10 at 21:22

Editor's gravatar image

Editor
46156156157

It's good.

IModule.OnDefinitionsBuilt is originally provided to allow extending the base model, but not to build the whole one. Building the whole model with T4 seems at least much simpler to debug.

(May 29 '10 at 21:22) Alex Yakunin Alex%20Yakunin's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA