Regarding this statement:
I'd expect the key column to be "PrimaryManagerFk" (as it was passed
into the mapping), and the one-to-many class to be "Project.Manager",
since one Manager has many Customers (this bag).

I think I was wrong about the second point, and the one-to-many class
is correctly set to Project.Customer. However, for the life of me I
cannot get the KeyColumnName to be set correctly.

A hypothesis that I have is that the automapping combined with the
override is confusing FluentNH because there is both a "many-to-one"
and a "many-to-many" relationship between the same two tables:

1 Manager -> many Customers (as Primary Manager)
many Managers -> many Customers (as Secondary Managers)

I've tried stepping through the Fluent mapping code, but I'm unsure
where exactly the problem occurs. I can't find where the KeyColumnName
is supposed to get used to generate the correct mapping...


On Jul 30, 6:07 pm, Chris Fazeli <[email protected]> wrote:
> So I've tried this mapping using and Override for the Business entity,
> rather than its joined subclasses:
>
> public class BusinessMap : IAutoMappingOverride<Business>
> {
>     public void Override(AutoMap<Business> mapping)
>     {
>         mapping.JoinedSubClass<Manager>("BusinessId")
>                .HasManyToMany<Customer>(x => x.SecondaryCustomers)
>                .WithTableName("ManagersToCustomers")
>                .WithParentKeyColumn("ManagerFk")
>                .WithChildKeyColumn("CustomerFk");
>
>         mapping.JoinedSubClass<Manager>("BusinessId")
>                .HasMany<Customer>(x => x.ManagedCustomers)
>                .KeyColumnNames.Add("PrimaryManagerFk")
>                .Inverse();
>
>         mapping.JoinedSubClass<Customer>("BusinessId")
>                .HasManyToMany<Manager>(x => x.SecondaryManagers)
>                .WithTableName("ManagersToCustomers")
>                .WithParentKeyColumn("CustomerFk")
>                .WithChildKeyColumn("ManagerFk");
>
>         mapping.JoinedSubClass<Customer>("BusinessId")
>                .References<Manager>(x => x.PrimaryManager);
>     }
>
> }
>
> It seems odd to have to do it this way, but if you explicitly state
> the inverse and the link table name, the mapping is done correctly:
> <joined-subclass name="Project.Manager, Project, Version=1.0.0.0,
> Culture=neutral, PublicKeyToken=null" table="Managers">
>   <key column="BusinessId" />
>   ...
>   <bag name="SecondaryCustomers" table="ManagersToCustomers">
>     <key column="ManagerFk" />
>     <many-to-many column="CustomerFk" class="Project.Customer,
> Project, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
>   </bag>
> </joined-subclass>
> <joined-subclass name="Project.Customer, Project, Version=1.0.0.0,
> Culture=neutral, PublicKeyToken=null" table="Customers">
>   <key column="BusinessId" />
>   ...
>   <bag name="SecondaryManagers" table="ManagersToCustomers">
>     <key column="CustomerFk" />
>     <many-to-many column="ManagerFk" class="Project.Manager, Project,
> Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
>   </bag>
> </joined-subclass>
>
> However, the Inverse HasMany mapping does not work, giving me a
> completely incorrect result under the Manager subclass:
> <bag name="ManagedCustomers" inverse="true">
>   <key column="ManagerFk" />
>   <one-to-many class="Project.Customer, Project, Version=1.0.0.0,
> Culture=neutral, PublicKeyToken=null" />
> </bag>
>
> I'd expect the key column to be "PrimaryManagerFk" (as it was passed
> into the mapping), and the one-to-many class to be "Project.Manager",
> since one Manager has many Customers (this bag).
>
> Any ideas what's going on? Why is the mapper not using my passed in
> KeyColumnName. What automatic detection should I be able to rely on?
>
> - Chris
>
> On Jul 30, 3:53 pm, Chris Fazeli <[email protected]> wrote:
>
> > Hi,
>
> > I have a Customer entity and a Manager entity. Both are joined
> > subclasses of a Business entity.
> > One customer can be managed by many managers:
> >     public virtual IList<Manager> Managers { get; set; }
> > One manager can manage many customers:
> >     public virtual IList<Customer> Customers { get; set; }
>
> > It is my understanding that automapping doesn't pick this up. So I map
> > manually with overrides:
> > public class CustomerMap : IAutoMappingOverride<Customer>
> > {
> >     public void Override(AutoMap<Customer> mapping)
> >     {
> >         mapping.HasManyToMany<Manager>(x => x.Managers)
> >             .AsBag()
> >             .WithTableName("ManagersCustomers")
> >             .WithParentKeyColumn("CustomerFk")
> >             .WithChildKeyColumn("ManagerFk");
> >     }
>
> > }
>
> > public class ManagerMap : IAutoMappingOverride<Manager>
> > {
> >     public void Override(AutoMap<Manager> mapping)
> >     {
> >         mapping.HasManyToMany<Customer>(x => x.Customers)
> >             .AsBag()
> >             .WithTableName("ManagersCustomers")
> >             .WithParentKeyColumn("ManagerFk")
> >             .WithChildKeyColumn("CustomerFk")
> >             .Inverse();
> >     }
>
> > }
>
> > These overrides are executed, but in
> > FluentNhibernate.AutoMap.AutoPersistenceModel, the MergeMap method
> > calls GetTypeToMap, and this does a check to see if the type's
> > basetype should be passed back. I get a failure here. Using S#arp
> > Arch's CanConfirmDatabaseMatchesMappings test, I see the exeption:
>
> >   ----> System.ArgumentException : Object of type
> > 'FluentNHibernate.AutoMap.AutoMap`1[Project.Customer]' cannot be
> > converted to type 'FluentNHibernate.AutoMap.AutoMap`1
> > [Project.Business]'.
> > TearDown : System.Reflection.TargetInvocationException : Exception has
> > been thrown by the target of an invocation.
> >   ----> System.Collections.Generic.KeyNotFoundException : The given
> > key was not present in the dictionary.
>
> > Can anyone help with this? I'm not quite sure what to do about it!
>
> > For completeness, there's also a one-to-many mapping between Managers
> > and Customers, where the customer has the notion of a PrimaryManager,
> > and an inverse relationship exists in the Manager as a list of
> > ManagedCustomers. I figure this gets picked up by the automapper.
>
> > Thanks,
> > - Chris
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Fluent NHibernate" 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/fluent-nhibernate?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to