Debugging Xml Output by FNH

1 view
Skip to first unread message

Troy Goode

unread,
Jan 8, 2009, 10:57:27 AM1/8/09
to Fluent NHibernate
I know from my recent foray into automapping that I can see what the
XML produced by the automapper is using:

automapper.WriteMappingsTo("folderpath");

What is the easiest way to accomplish the same thing (see the
generated XML) when using ClassMap<T>?

Andrew Stewart

unread,
Jan 8, 2009, 11:00:30 AM1/8/09
to fluent-n...@googlegroups.com
Hi Troy

You should be able to use PersistenceModel to write the mappings instead.

Andy
--
=================
I-nnovate Software - Bespoke Software Development, uk wirral.
http://www.i-nnovate.net

Mart Leet

unread,
Jan 8, 2009, 11:03:11 AM1/8/09
to fluent-n...@googlegroups.com
To see my xml in testexplorer i created this:
Console.Write(XElement.Parse(CreateMapping(new MappingVisitor()).FirstChild.NextSibling.InnerXml, LoadOptions.PreserveWhitespace).ToString());

Not much, but readable...

James Gregory

unread,
Jan 8, 2009, 11:05:06 AM1/8/09
to fluent-n...@googlegroups.com
As Andrew said, the PersistenceModel has a WriteMappingsTo(string folder) method.

Ryan Kelley

unread,
Jan 8, 2009, 11:17:02 AM1/8/09
to Fluent NHibernate
I believe that using the PersisitnceModel.WritemappingsTo yields
diferent results than the XML that is acutally used if you don't write
the mapings though. By different, I mean the order of the properties
are different. So as long as you are not concerned about what order
the properties come in then it should be fine. The other way is to do
something like this:

Use an IMappingVisitor to do this:

// This code is the caller to write the files
IList<IMapGenerator> mappers = GeneratorHelper.GetMapGenerators();
foreach (var mapper in mappers)
{
mapper.Generate().Save(mapper.FileName);

}

Each map I want to write out implements IMapGenerator

public XmlDocument Generate()
{
return CreateMapping(new MappingVisitor());
}

IMapGenerator code:

public interface IMapGenerator
{
string FileName { get; }
XmlDocument Generate();
}

On Jan 8, 10:05 am, "James Gregory" <jagregory....@gmail.com> wrote:
> As Andrew said, the PersistenceModel has a WriteMappingsTo(string folder)method.
>
> On Thu, Jan 8, 2009 at 4:03 PM, Mart Leet <mal...@gmail.com> wrote:
> > To see my xml in testexplorer i created this:Console.Write(XElement.Parse(CreateMapping(new
> > MappingVisitor()).FirstChild.NextSibling.InnerXml,
> > LoadOptions.PreserveWhitespace).ToString());
>
> > Not much, but readable...
>

James Gregory

unread,
Jan 8, 2009, 11:35:23 AM1/8/09
to fluent-n...@googlegroups.com
I'm still confused by how they can be different orders.

This is how the mappings are added to NHibernate:
public virtual void Configure(Configuration configuration)
{
  _configured = true;

  MappingVisitor visitor = new MappingVisitor(_conventions, configuration, _chain);
  _mappings.ForEach(mapping => mapping.ApplyMappings(visitor));
}

This is how they're written out:
public void WriteMappingsTo(string folder)
{
  DiagnosticMappingVisitor visitor = new DiagnosticMappingVisitor(folder, _conventions, null, _chain);
  _mappings.ForEach(m => m.ApplyMappings(visitor));
}

As you can see, they're nigh-on-identical.

Ryan Kelley

unread,
Jan 8, 2009, 2:08:41 PM1/8/09
to Fluent NHibernate
The only thing I can think of is maybe this in ClassMapBase:

protected void writeTheParts(XmlElement classElement, IMappingVisitor
visitor)
{
_properties.Sort(new MappingPartComparer());
foreach (IMappingPart part in _properties)
{
part.Write(classElement, visitor);
}
}

where it does the sort on the list before it adds them. Because when I
use CreateMapping vs WriteMappingsTo they are different and
CreateMapping is consistent with what the db/NH sees, unless you do
WriteMappingsTo then that is consistent.

On Jan 8, 10:35 am, "James Gregory" <jagregory....@gmail.com> wrote:
> I'm still confused by how they can be different orders.
> This is how the mappings are added to NHibernate:
> public virtual void Configure(Configuration configuration)
> {
>   _configured = true;
>
>   MappingVisitor visitor = new MappingVisitor(_conventions, configuration,
> _chain);
>   _mappings.ForEach(mapping => mapping.ApplyMappings(visitor));
>
> }
>
> This is how they're written out:
> public void WriteMappingsTo(string folder)
> {
>   DiagnosticMappingVisitor visitor = new DiagnosticMappingVisitor(folder,
> _conventions, null, _chain);
>   _mappings.ForEach(m => m.ApplyMappings(visitor));
>
> }
>
> As you can see, they're nigh-on-identical.
>

James Gregory

unread,
Jan 11, 2009, 5:51:18 PM1/11/09
to fluent-n...@googlegroups.com
Ryan, as far as I can tell WriteMappingsTo does nothing to affect the ordering of the properties. What exactly are you seeing that differs?

PersistenceModel.Configure uses the MappingVisitor which calls ApplyMappings on each mapping, which itself calls CreateMapping which uses writeTheParts and does the ordering.

PersistenceModel.WriteMappingsTo uses the DiagnosticMappingVisitor, and it does exactly the same as PersistenceModel.Configure except it writes the XmlDocument to the disk instead of pushing it into the NHibernate Configuration object. Nothing else differs.

So your call to CreateMapping still ends up calling writeTheParts which does the ordering, so they both end up doing the same thing.

Can you provide me with some concrete examples of what differs in the mappings? 

The post that Mart Leet linked to is regarding the ordering of the properties in the XML being different to the order that you map them in the ClassMap, and that's by design (although perhaps incorrect). So not exactly related.
Reply all
Reply to author
Forward
0 new messages