views:

196

answers:

2

If I have a parent class:

public class Parent
{
    public Parent()
    {
        Children = new List<Child>();
    }

    IList<Child> Children {get; private set;}
}

and a child class like so:

public class Child
{
     public SomeThirdClass Friend {get; set;}
}

Whenever I let the Fluent NHibernate's automapper hit these guys, it makes the Child class have a non-nullable foreign key. I have altered a few automapping conventions and some overrides for certain classes, but for this particular pair only the Parent class has an override. The override does not specify how to map the collection part for the Parent class.

Is making a foreign key not-nullable in the child of a collection the default behavior, or have I F'ed something up?

How would one specify in a mapping override class that the child foreign key is nullable?

PEACE!

+2  A: 

Have you tried this:

   public class ChildMap : IAutoMappingOverride<Child>
   {
       public void Override(AutoMapping<Child> mapping)
       {
           mapping.References(x => x.OtherThing)
               .Nullable();
       }
   }

If you want to make it the default for all your foreign keys, you can use this:

   public class NullableFKConvention : IReferenceConvention
   {
       public void Apply(IManyToOneInstance instance)
       {
           instance.Nullable();
       }
   }
Paul Batum
I'll give it a shot, I just assumed that you were only supposed to use .Reference for one to one relationships and HasMany for one to many relationships. But I guess that assumption was wrong.
Mark Rogers
The first solution yields this error:An association from the table Parent refers to an unmapped class: System.Collections.Generic.IList<Child>, I guess I have to let it map the collection. I was restricting the automapper to entitys that inherited from a base class. Still it seems a little ackward, even if it does end up working.
Mark Rogers
References() is for defining a many to one relationship, which is exactly what the relationship is between Child and SomeThirdClass in your example above, so its a fit. If you wanted Child to have a reference back to its Parent, you would also achieve that (if you weren't automapping) using References(). Not sure I follow your comment about awkwardness. Typically you let the automapper map your whole domain, and then you specify automapping overrides for the bit you want handled differently. How is your case different?
Paul Batum
Also you should check out the page on fluent mapping in the wiki, it has explanations for References and others. http://wiki.fluentnhibernate.org/Fluent_mapping
Paul Batum
Fair enough, I've used Fluent Nhibernate since it's inception, but I must have got confused somewhere between the last few updates to the automapper.
Mark Rogers
I think maybe I've failed to explain the question correctly. I read your link it says: ["References is for creating many-to-one relationships between two entities, and is applied on the "many side." You're referencing a single other entity, so you use the References method. HasMany is the "other side" of the References relationship, and gets applied on the "one side."] Because the child has no reference to the parent (in the class), I cannot use "References" because there is nothing to point to. Only the Parent points to child, therefore according to the link I should use HasMany.
Mark Rogers
HasMany and References are a pair that correspond to each side of a one-to-many relationship. But you don't have to have both. You can have a child that doesn't know about its parent (such as in your example), or a parent that doesn't know about its child (this is how foreign keys work in relational databases). In your example above, there is a one-to-many relationship between parent and child, but there is also a one-to-many relationship between SomeThirdClass and child. Thats why I said to use references on the relationship with the third class.
Paul Batum
That's what I gathered, I wasn't aware you could go the other way with Reference, that's good to know. I'm sorry if I've seen argumentative, thanks for all your hard work on the fluent Nhib project.
Mark Rogers
Not at all! Your welcome.
Paul Batum
A: 

I was able to solve the problem by removing a fluent mapping of a 4th GrandParent class, and allowing the automapper to map that class. Before I had not allowed the automapper to map the GrandParent class because I had a fluent mapping of that class. Somehow this conflict between fluent and auto mappings caused the foreign key in Child to be not-nullable.

I can't say that I completely understand what went wrong, so caution is advised when following my solution. But I can say that combining Fluent Mappings and Automappings definitely increases the complexity of debugging persistence issues.

Alternate Solution: I came across this problem again another two times, and I noticed that if I call KeyColumn(string columnName) in the IAutoMappingOverride for the Parent, the foreign key in the child class will default to Nullable, rather than Not-Null. Crazy Huh?

Mark Rogers
Mixing fluent maps and automapping can indeed be awkward. The IAutomappingOverride interface gives you pretty much all the capabilities that fluent maps do and it does it in a manner that plays nicely with automapping. Since you are using automapping, I suggest you try to use IAutomappingOverride wherever possible rather than ClassMaps.
Paul Batum