In practice:
public class Document
{
public Document()
{
Created = DateTime.Now;
Parts = new List<DocumentPart>();
}

public virtual int Id { get; protected set; }
public virtual DateTime Created { get; set; }
public virtual string Title { get; set; }
public virtual string Author { get; set; }
public virtual ICollection<DocumentPart> Parts { get; set; }
}

public class DocumentPart
{
protected DocumentPart() {}

public DocumentPart(Document document)
{
Document = document;
}

public virtual int Id { get; protected set; }
public Document Document { get; private set; }
public virtual string Content { get; set; }
}

public class DerivedPart : DocumentPart
{
public virtual string ExtraField { get; set; }
}
The parent-child can be implemented in others ways and you should
implement IEqualityComparer
Then the mapping is
public void MapDomain(ObjectRelationalMapper orm)
{
orm.TablePerClass<Document>();
orm.TablePerClassHierarchy<DocumentPart>();

orm.Patterns.PoidStrategies.Add(new NativePoidPattern());
}
public void CustomizeMapper(Mapper mapper)
{
mapper.Customize<Document>(cm =>
{
cm.Property(doc => doc.Title, pm =>
{
pm.NotNullable(true);
pm.Length(20);
});
cm.Property(doc => doc.Author, pm => pm.Index("idx_author"));
});
}

The integration with NHibernate is:
var orm = new ObjectRelationalMapper();
IDomainMapping domainMapping;

domainMapping = new MihaValencicMapping();

domainMapping.MapDomain(orm);

var mapper = new Mapper(orm);
domainMapping.RegisterPatterns(mapper);
domainMapping.CustomizeMapper(mapper);

var nhconf = ConfigureSessionFactory();
nhconf.AddDeserializedMapping(mapper.CompileMappingFor(domainMapping.GetDomainClasses()),
"FullDomain");

The implementation of ConfigureSessionFactory is obviously using the
standard NHibernate.Configuration class
public Configuration ConfigureSessionFactory()
{
var configure = new Configuration();
configure.SessionFactoryName("Demo");
configure.Proxy(p =>
{
p.ProxyFactoryFactory<ProxyFactoryFactory>();
});
configure.DataBaseIntegration(db =>
{
db.Dialect<MsSql2008Dialect>();
db.Driver<SqlClientDriver>();
db.KeywordsAutoImport = Hbm2DDLKeyWords.AutoQuote;
db.IsolationLevel = IsolationLevel.ReadCommitted;
db.ConnectionString = TheConnectionString;
db.Timeout = 10;
db.HqlToSqlSubstitutions = "true 1, false 0, yes 'Y', no 'N'";
});
return configure;
}

If you want see XMLs, the mapping is:
  <class name="Document">
    <id name="Id" type="Int32">
      <generator class="native" />
    </id>
    <property name="Created" />
    <property name="Title" length="20" not-null="true" />
    <property name="Author" index="idx_author" />
    <bag name="Parts" inverse="true" cascade="all,delete-orphan">
      <key column="Document" on-delete="cascade" />
      <one-to-many class="DocumentPart" />
    </bag>
  </class>
  <class name="DocumentPart">
    <id name="Id" type="Int32">
      <generator class="native" />
    </id>
    <discriminator />
    <many-to-one name="Document" />
    <property name="Content" />
  </class>
  <subclass name="DerivedPart" extends="DocumentPart">
    <property name="ExtraField" />
  </subclass>

WHO WROTE THE MAPPING ?

2010/3/29 Fabio Maulo <[email protected]>

> Well... that should be a classic parent-child and the relation should be
> bidirectional.
> The bidirectional association work for sure what is wrong is your
> implementation.
> If you don't want a bidirectional one-to-many try to guess who are in
> charge of deletation of children.
>
> 2010/3/28 Miha V <[email protected]>
>
> @nadav. I saw posts suggesting that inverse="true" should be used, but
>> those are mainly for bi-directional associations. Nevertheless, I have
>> tried it, and it didn't help. Even more, it didn't work at all!
>> (foreign key was not populated)
>>
>> @Fabio: the classes are here: http://dl.dropbox.com/u/163584/NHModels.zip
>> .
>> If needed, I can prepare a complete repro solution.
>>
>> On Mar 28, 7:43 pm, Fabio Maulo <[email protected]> wrote:
>> > Can you send the classes ?
>> > I would see something.
>> >
>> > 2010/3/28 Miha V <[email protected]>
>> >
>> >
>> >
>> > > Hi!
>> >
>> > > I'm trying to figure out, why NHibernate inserts the entity, and then
>> > > (only if within transaction) updates the entity with foreign key.
>> >
>> > > The setup:
>> > > EntityA
>> > >  PropA
>> > >  IList<EntityB> PropB
>> >
>> > > EntityB
>> > >  PropC
>> > >  PropD
>> >
>> > > I'm using FluentNH to configure this, and the generated HBM looks
>> > > correct, and EntityB gets a foreign key EntityA_id. What's weird
>> > > though is this:
>> >
>> > > 1) If I'm not in the transaction, NH only inserts Entity in DB,
>> > > without populating foreign key EntityA_id. This results in orphan
>> > > elements in the databse and, well, it's incorrect since EntityA has no
>> > > children. The cascade is set to all.
>> >
>> > > 2) If I'm in the transaction, NH **updates** the EntityB table
>> > > **after** inserts with the foreign key. This works and is correct, but
>> > > the update at the end should IMHO be moved to "insert phase".
>> >
>> > > Question1: Why does this behaviour change whether I'm in a transaction
>> > > or not?
>> >
>> > > Question2: is there a way to "force" NH to populate the foreign key in
>> > > the insert?
>> >
>> > > For reference, here are the actual HBM files: (Document contains
>> > > DocumentPart(s))
>> > >http://dl.dropbox.com/u/163584/HBM.zip
>> >
>> > > Thanks,
>> > >  Miha.
>> >
>> > > --
>> > > You received this message because you are subscribed to the Google
>> Groups
>> > > "nhusers" group.
>> > > To post to this group, send email to [email protected].
>> > > To unsubscribe from this group, send email to
>> > > [email protected]<nhusers%[email protected]>
>> <nhusers%[email protected]<nhusers%[email protected]>
>> >
>> > > .
>> > > For more options, visit this group at
>> > >http://groups.google.com/group/nhusers?hl=en.
>> >
>> > --
>> > Fabio Maulo
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "nhusers" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected]<nhusers%[email protected]>
>> .
>> For more options, visit this group at
>> http://groups.google.com/group/nhusers?hl=en.
>>
>>
>
>
> --
> Fabio Maulo
>
>


-- 
Fabio Maulo

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to