Boz,

                                            

If TypeA always has null for the collection property, can you not just
move the property to the subclass TypeB, then all your problems go away:

 

class TypeA {

    int Id;

    string Name;

}

 

class TypeB : TypeA {

    IList<Child> Children;

}

 

class Child {

    ....

}

 

class TypeAClassMap : ClassMap<TypeA>{

    public TypeAClassMap() {

        Id(x=>x.Id);

        Map(x=>x.Name);

        DiscriminateSubclassesOnColumn("type")

    }

}

 

class TypeBClassMap : SubClassMap<TypeB>{

    public TypeBClassMap() {

        HasMany(x=>x.Children);

    }

}

 

 

From: fluent-nhibernate@googlegroups.com
[mailto:fluent-nhibern...@googlegroups.com] On Behalf Of Hudson Akridge
Sent: 04 January 2010 16:43
To: fluent-nhibernate@googlegroups.com
Subject: Re: [fluent-nhib] Re: Discriminating sub classes with null
values?

 

While you can *technically* do what you're looking for with a formula
discriminator, that is, in my book, a horrid hack and like any "good"
hack, will cause you unforseen problems down the road.

 

What Paul is recommending is more of a state based function, and would
be a better solution imo. Inheritance isn't going to work out so great
for you here. Inheritance should not be decided based on the state of
the object, but rather it's intended purpose. To do otherwise blurs the
lines of object state and object type. Type is stateless, it's always
stateless. If someone is a manager, they are always a manager, it
doesn't matter what state they're in, they are still a manager. If
there's an association that determines the type, you're declaring that
your type can change at any moment. Whether or not that's true/enforced
in your business model, that is what your class definition is stating.

 

What it looks like you need, is to change function based on state. A
classic state machine, with a state factory that generates you the
proper functional state class depending on the class state you pass in.
Going the route of Paul's suggestion gives you the ability to change how
your class behaves depending on it's state.

 

It is what I would highly recommend doing.

 

On Mon, Jan 4, 2010 at 9:53 AM, Boz <jjkbosw...@yahoo.com> wrote:

Thanks for responding Paul.

I'm not sure I fully understand your response or whether I've phrased
my question wrong.  I see what you mean about not wanting to have
objects in an invalid state at runtime, however wouldn't that always
be the case for when you use DiscriminateSubClassesOnColumn?  i.e. are
you saying the discriminator mapping should never be used?

In my particular case the two classes are different and instances are
not intended to be switched, even though they get their data from the
same table.  So, although records in TableA can be of TypeA or TypeB,
there's no intention that setting a property of TypeA would make it a
TypeB or viceversa, and the class and mapping wouldn't permit that.

Also, the use of delegating the behaviour... did you intend that I
would have just TypeA mapping to TableA, and then have two "behaviour"
classes?  In my case, the behaviours are not polymorphic and in some
instances of the class the properties and behaviour would not be
implemented.

So I'm not sure if we're talking about different things here or if I
have just got this all wrong.

A colleague has found that it is possible to achieve a "not null"
subclass discrimination in nHibernate by use of formulas:
http://stackoverflow.com/questions/1664936/nhibernate-inheritance-discri
minator-value
 <discriminator formula="case when discriminatorID = '' then 1 else 2
end"/>

and Fluent supports DiscriminatorPart.Formula(string sql), i.e.:
 DiscriminateSubClassesOnColumn("discriminatorID")
  .Formula("case when discriminatorID = '' then 1 else 2 end");

So I can achieve what I need to but I need to understand if its right
to, based on your points in your response.

Thanks

Boz


On Dec 30 2009, 11:07 am, Paul Batum <paul.ba...@gmail.com> wrote:
> This idea sounds dangerous to me. You can't have an object "change
> class" at runtime, so what is supposed to happen when your
> relationship changes (either a record with a NULL gets a valid FK or
> vice versa, the FK is nulled out)? Suddenly the state of your object
> no longer makes sense.
>
> I suggest you move away from mapping this with inheritance. You can
> still use inheritance to achieve the desired polymorphic behavior
> based on the whether the FK is null or not, via delegation:
>
> public class StaffMember
> {
>   public StaffMember Manager { get; set; }
>
>   public void PerformCalculationOne()
>   {
>      InnerCalculator.PerformCalculationOne();
>   }
>
>   public void PerformCalculationTwo()
>   {
>      InnerCalculator.PerformCalculationTwo();
>   }
>
>   private StaffCalculator InnerCalculator
>   {
>      get {  return Manager == null ? new NoManagerCalculator() : new
> DefaultCalculator(); }
>   }
>
> }
>

> 2009/12/21Boz<jjkbosw...@yahoo.com>:

>
> > Hi,
>
> > Some help on the following situation would be much appreciated...
>
> > I've got two tables that on the face of it have a normal 1 to many
> > relationship, i.e. records in TableA have a reference to a record in
> > TableB, however the relationship is optional because the field can
be
> > null, i.e. zero or 1 to many. relationship
>
> > I want to model two distinct types of object for TableA, those with
> > that foreign relationship and those without (as conceptually the
> > business entities are different enough ).  It would make sense to
have
> > a ClassMap and SubClassMap for those 2 entities, where SubClassMap
is
> > discriminated on the column that has the optional foreign
relationship
> > (DiscriminateSubColumClassesOnColumn)
>
> > But, 2 problems:
> > 1) In SubClassMap, how do I discriminate on "Not Null" for that
field,
> > so that the sub class only leads to objects with that foreign
> > relationship.
> > 2) How do I ensure the parent class only leads to objects that have
> > Null in that field.
>
> > For 2), I can only really see that I'd have an abstract base and 2
> > subclasses, but one of the subclasses wouldn't derive any new data,
> > it's just a concrete version of the abstract base.
>
> > Anyway, I hope that all makes sense, I'm very new to NHibernate and
> > Fluent, so apologies if I've missed some very obvious concepts.
>
> > Thanks
>
> >Boz
>
> > --
>
> > You received this message because you are subscribed to the Google
Groups "Fluent NHibernate" group.
> > To post to this group, send email to
fluent-nhibern...@googlegroups.com.
> > To unsubscribe from this group, send email to
fluent-nhibernate+unsubscr...@googlegroups.com
<mailto:fluent-nhibernate%2bunsubscr...@googlegroups.com> .

> > For more options, visit this group
athttp://groups.google.com/group/fluent-nhibernate?hl=en.


--

You received this message because you are subscribed to the Google
Groups "Fluent NHibernate" group.
To post to this group, send email to fluent-nhibern...@googlegroups.com.
To unsubscribe from this group, send email to
fluent-nhibernate+unsubscr...@googlegroups.com
<mailto:fluent-nhibernate%2bunsubscr...@googlegroups.com> .
For more options, visit this group at
http://groups.google.com/group/fluent-nhibernate?hl=en.






-- 
- Hudson
http://www.bestguesstheory.com
http://twitter.com/HudsonAkridge

--

You received this message because you are subscribed to the Google
Groups "Fluent NHibernate" group.
To post to this group, send email to fluent-nhibern...@googlegroups.com.
To unsubscribe from this group, send email to
fluent-nhibernate+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/fluent-nhibernate?hl=en.

--

You received this message because you are subscribed to the Google Groups 
"Fluent NHibernate" group.
To post to this group, send email to fluent-nhibern...@googlegroups.com.
To unsubscribe from this group, send email to 
fluent-nhibernate+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/fluent-nhibernate?hl=en.


Reply via email to