MapEntitiesFromAssembly<T> creates an instance of an AutoPersistenceModel, so you'd need to do something like this to use multiple assemblies: var autoMapper1 = AutoPersistenceModel.MapEntitiesFromAssembly<A>(); var autoMapper2 = AutoPersistenceModel.MapEntitiesFromAssembly<B>();
The problem is, that would only map two separate class hierarchies, and not handle any mixing of the two. I don't think it's currently possible to map two assemblies as one logical domain. This is something that we should support though. On Thu, Feb 12, 2009 at 5:20 PM, Jimit <[email protected]> wrote: > > That unfortunately raises other issues for me - all my base classes > including DomainObject are in another assembly (Core.Common) than the > one that holds my domain model (Core.Domain). I don't suppose it's > possible to call MapEntitiesFromAssembly<T> more than once and filter > it with the same predicate in the Where method? I seem to remember > MapEntitiesFromAssembly<T> simply saving a reference to the assembly > for use later in CompileMappings which would mean that calling it > twice would simply reset the reference. > What do you think? > > On Feb 12, 8:54 am, James Gregory <[email protected]> wrote: > > Yeah, that makes sense. Currently you shouldn't exclude something set > with > > IsBaseType in your Where clause. That being said, the two should probably > > be equivalent really. > > > > > > > > On Thu, Feb 12, 2009 at 6:10 AM, Jimit <[email protected]> wrote: > > > > > I think I may have found the problem. DomainObject was excluded by my > > > entity filter in my call to Where on the AutoPersistenceModel (since > > > it itself is not an entity, just a common base class for both entities > > > and value objects and thus it doesn't have an Id, I figured no need). > > > I subsequently did a mapping override using > > > ForTypesThatDeriveFrom<DomainObject> which internally populates an > > > AutoMap<DomainObject>. In CompileMappings however the conditions that > > > would normally exclude DomainObject from the final mapping (i.e the > > > checks for shouldInclude and IsBaseType) don't get called for > > > DomainObject since it was not in the original list of entities to map. > > > It's AutoMap<DomainObject> created by ForTypesThatDeriveFrom is meant > > > only to be used by MergeMapping to merge with automaps for classes > > > deriving from DomainObject and instead it went to AddMapping. As a > > > result it circumvents the checks and ends up getting mapped. Not > > > having an Id property, Nhibernate doesn't like that and hence the > > > exception. I haven't actually checked the call stacks to verify this > > > behaviour - it's all been mental compiler since the realization just > > > came to me. :) I'll check it out when I'm at work but it seems to be > > > pointing at a loophole in the CompileMapping logic. > > > > > On Feb 10, 10:54 pm, Jimit <[email protected]> wrote: > > > > This is my test fixture. I configure FNH in the Setup: > > > > > > [TestFixture] > > > > public class PersistenceTests > > > > { > > > > #region Setup/Teardown > > > > > > [SetUp] > > > > public void SetUp() > > > > { > > > > _sessionFactory = Fluently.Configure() > > > > .Database(SQLiteConfiguration.Standard.InMemory) > > > > .Mappings(m => m.AutoMappings.Add(Mapper.Mappings)) > > > > .ExposeConfiguration(cfg => new SchemaExport > > > > (cfg).Create(true, true)) > > > > .BuildSessionFactory(); > > > > } > > > > > > [TearDown] > > > > public void TearDown() > > > > { > > > > _sessionFactory = null; > > > > } > > > > > > #endregion > > > > > > private ISessionFactory _sessionFactory; > > > > > > [Test] > > > > public void Can_Map_Orders_To_Database() > > > > { > > > > new PersistenceSpecification<Order> > > > > (_sessionFactory.OpenSession()) > > > > .CheckProperty(o => o.Reference, "Order Ref 1") > > > > .CheckProperty(o => o.PartsOrdered, 2) /* and so > > > > on...*/ > > > > .CheckProperty(o => o.PartsReceived, 1); > > > > } > > > > > > } > > > > > > Mapper.Mappings is where the AutoPersistenceModel is defined. Here > are > > > > the pertinent parts there: > > > > > > public static class Mapper > > > > { > > > > public static AutoPersistenceModel Mappings > > > > { > > > > get > > > > { > > > > return _mappings ?? (_mappings = DefineMappings()); > > > > } > > > > } > > > > > > private static AutoPersistenceModel DefineMappings() > > > > { > > > > return AutoPersistenceModel > > > > .MapEntitiesFromAssemblyOf<Order>() > > > > .Where(EntityFilter) > > > > .WithConvention(DefineConventions) > > > > .WithCustomMappingsFrom<CustomMappings>(); > > > > } > > > > > > private static void DefineConventions > > > > (FluentNHibernate.Conventions conventions) > > > > { > > > > SetDefaultConventions(conventions); > > > > AddCustomConventions(conventions); > > > > } > > > > private static void SetDefaultConventions > > > > (FluentNHibernate.Conventions conventions) > > > > { > > > > conventions.GetPrimaryKeyName = property => property.Name > > > > + "Id"; > > > > conventions.GetPrimaryKeyNameFromType = type => type.Name > > > > + "Id"; > > > > conventions.GetVersionColumnName = property => "Version"; > > > > conventions.IsBaseType = type => > > > > type == typeof (object) || > > > > type == typeof (DomainObject) || > > > > (type.IsGenericType > > > > && > type.GetGenericTypeDefinition > > > > ().IsIn(new[] > > > > > > { > > > > > > typeof (EntityBase<,>), > > > > > > typeof (EntityBase<>), > > > > > > typeof (ProcessedEntity<,>), > > > > > > typeof (ProcessedEntity<>), > > > > > > typeof (AuditedEntity<,>), > > > > > > typeof (AuditedEntity<>), > > > > > > typeof (ProcessingEvent<>) > > > > > })); > > > > //conventions.IsComponentType = t => t == > typeof(Address); > > > > conventions.OneToManyConvention = map => > > > > map.Cascade.SaveUpdate(); > > > > conventions.DefaultLazyLoad = true; > > > > conventions.GetForeignKeyNameOfParent = parent => > > > > parent.Name + "ID"; > > > > conventions.IdConvention = identity => identity > > > > .Access. > > > > > > AsReadOnlyPropertyThroughPascalCaseField > > > > > > (Prefix.Underscore) > > > > > .GeneratedBy.Native > > > > () > > > > > .TheColumnNameIs > > > > ("Id"); > > > > conventions.GetForeignKeyName = property => property.Name > > > > + "Id"; > > > > conventions.GetManyToManyTableName = > > > > (parent, child) => parent.Name + "_" + child.Name; > > > > conventions.DefaultCache = cache => cache.AsReadWrite(); > > > > conventions.GetParentSideForManyToMany = (type1, type2) > => > > > > { > > > > var > types > > > > = (new[] {type1, type2}) > > > > > .OrderBy > > > > (t => t.Name); > > > > return > > > > types.Where( > > > > > > t => typeof (IAggregateRoot) > > > > > .IsAssignableFrom > > > > (t)) > > > > > .FirstOrDefault > > > > () ?? > > > > > > types.First(); > > > > }; > > > > } > > > > > > private static void AddCustomConventions > > > > (FluentNHibernate.Conventions conventions) > > > > { > > > > // Add type conventions > > > > conventions.AddTypeConvention(new > DescriptionTypeConvention > > > > ()); > > > > conventions.AddTypeConvention(new NameTypeConvention()); > > > > conventions.AddTypeConvention(new ReferenceTypeConvention > > > > ()); > > > > > > // Add property conventions > > > > conventions.AddPropertyConvention(new > > > > ForeignKeyMapsToEnum<Order>(o => o.Status)); > > > > conventions.AddPropertyConvention(new AuditingConvention > > > > ()); > > > > } > > > > > > public static AutoPersistenceModel > > > > WithCustomMappingsFrom<TCustomMapper>(this AutoPersistenceModel > model) > > > > { > > > > (from method in typeof (TCustomMapper).GetMethods() > > > > where method.DeclaringType == typeof (TCustomMapper) > > > > && method.ReturnType == typeof (void) > > > > && method.GetParameters().Count() == 1 && > > > > method.GetParameters()[0].ParameterType. > > > > GetGenericTypeDefinition() == > > > > typeof (AutoMap<>) > > > > select method).ForEach(method => > > > > { > > > > var autoMapType = > > > > method.GetParameters()[0].ParameterType; > > > > var entityType = > > > > autoMapType.GetGenericArguments()[0]; > > > > var actionType = typeof > > > > (Action<>).MakeGenericType(new[] {autoMapType}); > > > > var mappingAction = new[] > > > > {Delegate.CreateDelegate(actionType, method)}; > > > > > > InvocationHelper.InvokeGenericMethodWithDynamicTypeArguments( > > > > model, > > > > map => > > > > map.ForTypesThatDeriveFrom<Object>(null), > > > > mappingAction, > > > > entityType); > > > > }); > > > > return model; > > > > } > > > > > > } > > > > > > The relevent action in CustomMappings is: > > > > > > public class CustomMappings > > > > { > > > > public static void ProcessMapping(AutoMap<DomainObject> map) > > > > { > > > > map.Version(o => o.Version) > > > > .Access.AsReadOnlyPropertyThroughPascalCaseField > > > > (Prefix.Underscore); > > > > map.IgnoreProperty(o => o.IsValid); > > > > map.IgnoreProperty(o => o.Error); > > > > } > > > > > > // other mapping overrides > > > > } > > > > > > On Feb 10, 12:07 pm, James Gregory <[email protected]> wrote: > > > > > > > Can we see how you're setting your conventions and where you're > > > plumbing FNH > > > > > into NHibernate? > > > > > > > On Tue, Feb 10, 2009 at 12:01 PM, Jimit <[email protected]> > wrote: > > > > > > > > I get the following error when attempting to test my mappings: > > > > > > > > <?xml version="1.0" encoding="utf-8"?> > > > > > > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default- > > > > > > lazy="true" assembly="Core.Common" > namespace="Core.Common.Entities"> > > > > > > <class name="DomainObject" table="`DomainObject`" > > > > > > xmlns="urn:nhibernate-mapping-2.2"> > > > > > > <cache usage="read-write" /> > > > > > > <version > > > > ... > > > > read more ยป- Hide quoted text - > > > > - Show quoted text - > > > --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
