On Thu, Dec 31, 2015 at 4:56 PM, Michael Powell <mwpowell...@gmail.com> wrote: > On Thu, Dec 31, 2015 at 3:31 PM, Michael Powell <mwpowell...@gmail.com> wrote: >> On Thu, Dec 31, 2015 at 3:30 PM, Michael Powell <mwpowell...@gmail.com> >> wrote: >>> On Thu, Dec 31, 2015 at 2:41 PM, Michael Powell <mwpowell...@gmail.com> >>> wrote: >>>> Hello, >>>> >>>> I have some confusion about how to best handle meta-ownership of >>>> parent/child records. Briefly, I have a statistics table whose rows >>>> may be owned by one of several parent tables. >>> >>> I got past that bit, but now on the return trip, reading the values >>> back out of the database, I am getting messages about the parent's Id. >>> Somehow this is ignoring the Id conventions, or I want to verify that >>> the convention includes this as a use case, not quite certain as to >>> which (?).
Pretty sure I have it nailed this time. Where I map the one to many, HasMany Cohorts: HasMany(x => x.Cohorts) .LazyLoad() .Inverse() .AsBag() .Where(string.Format(@"HostModelType = '{0}'", typeof (T).FullName)) .KeyColumn(@"HostModelId") .Cascade.AllDeleteOrphan(); Note the KeyColumn is set accordingly. Could get more fluent there, with properties, suffixes, conventions, but that's generally the idea. Which now that I look at it, makes perfect sense. > Here are the HBM's exported after successfully configuring the session > in and of itself. > > For Slot: > <bag access="field.camelcase-underscore" > cascade="all-delete-orphan" inverse="true" lazy="true" name="Cohorts" > where="HostModelType = 'Football.Models.Slot'"> > <key> > <column name="SlotId" /> > </key> > <one-to-many > class="Football.Models.Statistics.StatisticalCohort, Football, > Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" /> > </bag> > > In another host model: > > <bag access="field.camelcase-underscore" > cascade="all-delete-orphan" inverse="true" lazy="true" name="Cohorts" > where="HostModelType = 'Football.Models.Play'"> > <key> > <column name="PlayId" /> > </key> > <one-to-many > class="Football.Models.Statistics.StatisticalCohort, Football, > Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" /> > </bag> > > Somehow SlotId and PlayId are being inferred, but I do not see > extension methods, etc, that might lead me to believe I could set the > relevant Id property. > > Id's for my domain models are "Id", configured in their mappings. No > reason for them to be different here, either. > > And in the Cohort itself: > > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"> > <class xmlns="urn:nhibernate-mapping-2.2" > name="Football.Models.Statistics.StatisticalCohort, Football, > Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" > table="StatisticalCohorts"> > <id name="Id" type="System.Guid, mscorlib, Version=4.0.0.0, > Culture=neutral, PublicKeyToken=b77a5c561934e089"> > <column name="Id" not-null="true" /> > <generator class="guid.comb" /> > </id> > <bag access="field.camelcase-underscore" > cascade="all-delete-orphan" inverse="true" lazy="true" > name="Statistics"> > <key> > <column name="StatisticalCohortId" /> > </key> > <one-to-many class="Football.Models.Statistics.Statistic, > Football, Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" > /> > </bag> > <property name="Type" > type="NHibernate.Type.EnumStringType`1[[Football.Models.StatisticalCohortType, > Football, Version=1.44.0.29778, Culture=neutral, > PublicKeyToken=null]], NHibernate, Version=4.0.0.4000, > Culture=neutral, PublicKeyToken=aa95f207798dfdb4"> > <column name="Type" not-null="true" /> > </property> > <property name="CreatedOn" type="System.DateTime, mscorlib, > Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> > <column name="CreatedOn" not-null="true" /> > </property> > <any cascade="none" id-type="System.Guid, mscorlib, > Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > meta-type="System.String, mscorlib, Version=4.0.0.0, Culture=neutral, > PublicKeyToken=b77a5c561934e089" name="HostModel"> > <meta-value value="Football.Models.Team" > class="Football.Models.Team, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.TeamParticipation" > class="Football.Models.TeamParticipation, Football, > Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.Roster" > class="Football.Models.Roster, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.Game" > class="Football.Models.Game, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.GameSchedule" > class="Football.Models.GameSchedule, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.GameSituation" > class="Football.Models.GameSituation, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.BallContainer" > class="Football.Models.BallContainer, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.Play" > class="Football.Models.Play, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Models.Slot" > class="Football.Models.Slot, Football, Version=1.44.0.29778, > Culture=neutral, PublicKeyToken=null" /> > <meta-value > value="Football.Mechanics.Models.CharacteristicTrait" > class="Football.Mechanics.Models.CharacteristicTrait, Football, > Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" /> > <meta-value value="Football.Mechanics.Models.SkillTrait" > class="Football.Mechanics.Models.SkillTrait, Football, > Version=1.44.0.29778, Culture=neutral, PublicKeyToken=null" /> > <column name="HostModelType" /> > <column name="HostModelId" /> > </any> > </class> > </hibernate-mapping> > > All this leads me to wonder, is this a use case that needs to be > picked up by Fluent and/or NHibernate? Or have I missed something in a > convention, in a mapping, etc? > >>> I verified in the database, the child records are indeed saved, the >>> hosting model type full name is correctly represented, but the Id is >>> showing in an "unconventional" way, at least how I think I've got the >>> conventions mapped. But I could be wrong. >>> >>> Exception messages: >>> >>> SQL: SELECT cohorts0_.SlotId as SlotId1_, cohorts0_.Id as Id1_, >>> cohorts0_.Id as Id654_0_, cohorts0_.Type as Type654_0_, >>> cohorts0_.CreatedOn as CreatedOn654_0_, cohorts0_.HostModelType as >>> HostMode4_654_0_, cohorts0_.HostModelId as HostMode5_654_0_ FROM >>> StatisticalCohorts cohorts0_ WHERE >>> (System.Linq.Expressions.PropertyExpression = Football.Models.Slot) >>> and cohorts0_.SlotId=? >>> >>> could not initialize a collection: >>> [Football.Models.Slot.Cohorts#cac80bb6-3c7b-4784-a99c-a57f00fd21ee][SQL: >>> SELECT cohorts0_.SlotId as SlotId1_, cohorts0_.Id as Id1_, >>> cohorts0_.Id as Id654_0_, cohorts0_.Type as Type654_0_, >>> cohorts0_.CreatedOn as CreatedOn654_0_, cohorts0_.HostModelType as >>> HostMode4_654_0_, cohorts0_.HostModelId as HostMode5_654_0_ FROM >>> StatisticalCohorts cohorts0_ WHERE >>> (System.Linq.Expressions.PropertyExpression = Football.Models.Slot) >>> and cohorts0_.SlotId=?] >>> >>> The multi-part identifier "System.Linq.Expressions.PropertyExpression" >>> could not be bound. >> >> Should also clarify, the Slots table has an `Id` column, not a >> `SlotId` column, by design. Only somewhere I need to inform the >> conventions (?). >> >>>> In order to do this, I am using Fluent's AddMetaValue from the >>>> AnyPart<T>, but I think I am confused about its usage. >>>> >>>> Somewhere along the way I thought this applied to typeof (TModel) with >>>> a valueMap of typeof (TClassMap) where TClassMap is ClassMap<T>. >>>> >>>> Initial assignment of the domain model is correct. I assign instance >>>> of Parent to Child class' HostModel property. Type shows typeof >>>> (Parent), all is well. >>>> >>>> However, when the object saves, the meta value shows ParentMap, which >>>> I do not think is correct, and hence part of my confusion. >>>> >>>> Here's an example of my extension method to handle this. I know what I >>>> was driving for, but I don't recall why I was assuming TClassMap? >>>> Except, perhaps as a way of enforcing that TClass should be mapped. >>>> >>>> public static AnyPart<T> AddMetaValue<T, TClass, TClassMap>(this >>>> AnyPart<T> part) >>>> where TClassMap : ClassMap<TClass> >>>> where TClass : T >>>> { >>>> return part.AddMetaValue(typeof (TClass), typeof (TClassMap).Name); >>>> } >>>> >>>> I think probably that should read more like: >>>> >>>> return part.AddMetaValue(typeof (TClass), typeof (TClass).Name); >>>> >>>> Thoughts? Insights? >>>> >>>> Thank you, >>>> >>>> Michael Powell -- You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group. To unsubscribe from this group and stop receiving emails from it, send an email to fluent-nhibernate+unsubscr...@googlegroups.com. To post to this group, send email to fluent-nhibernate@googlegroups.com. Visit this group at https://groups.google.com/group/fluent-nhibernate. For more options, visit https://groups.google.com/d/optout.