An association from the table X refers to an unmapped class: System.Guid

16,586

Solution 1

These are wrong:

public virtual Guid UserId { get; set; }
public virtual Guid LocationId { get; set; }

And so are these:

CompositeId()
    .KeyReference(x => x.UserId, "UserId")
    .KeyReference(x => x.Attachment.Id, "AttachmentId")
    .KeyReference(x => x.LocationId, "LocationId");

You should have proper references:

public virtual User User { get; set; }
public virtual Location Location { get; set; }

And mapping:

CompositeId()
    .KeyReference(x => x.User, "UserId")
    .KeyReference(x => x.Attachment, "AttachmentId")
    .KeyReference(x => x.Location, "LocationId");

Solution 2

If you want to map simple properties in a composite key (it's not a "standard way" of relating things with a ORM, but in some cases it could help you) you can map the key using KeyProperty instead of KeyReference in this way:

CompositeId()
    .KeyProperty(x => x.UserId, "UserId")
    .KeyProperty(x => x.AttachmentId, "AttachmentId")
    .KeyProperty(x => x.LocationId, "LocationId");
Share:
16,586
Elad Benda
Author by

Elad Benda

linkedin

Updated on June 04, 2022

Comments

  • Elad Benda
    Elad Benda almost 2 years

    I have this class:

    public class AttachmentLocation
    {
        #region properties
    
        public virtual Guid UserId { get; set; }
    
        public virtual Guid LocationId { get; set; }
    
        public virtual long IndexInLocation { get; set; }
    
        #endregion
    
        #region contained foreign objects
    
        public virtual Attachment Attachment { get; set; }
    
        #endregion
    
    
        #region Methods need to override for CompositeId
    
        public override bool Equals(object obj)
        {
            if (obj == null)
                return false;
            var t = obj as AttachmentLocation;
            if (t == null)
                return false;
            if (UserId == t.UserId && LocationId == t.LocationId && Attachment.Id == t.Attachment.Id)
                return true;
            return false;
        }
    
        public override int GetHashCode()
        {
            return (UserId + "|" + LocationId + "|" + Attachment.Id).GetHashCode();
        }
    
        #endregion
    
    }
    

    I have this Fluent Mapping:

    public class AttachmentLocaionMap : ClassMap<AttachmentLocation>
    {
        public AttachmentLocaionMap()
        {
            Table("Metadata_AttachmentLocation");
            CompositeId()
                .KeyReference(x => x.UserId, "UserId")
                .KeyReference(x => x.Attachment.Id, "AttachmentId")
                .KeyReference(x => x.LocationId, "LocationId");
            Map(x => x.IndexInLocation).Not.Nullable();
            Map(x => x.LocationId).Not.Nullable();
    
            HasOne(x => x.Attachment);
        }
    }
    

    which I register:

    SessionFactory = Fluently.Configure(configuration).Mappings(m =>
    {
        m.FluentMappings.AddFromAssemblyOf<AttachmentLocaionMap>();           
        m.FluentMappings.AddFromAssemblyOf<FriendDetailsMap>();
    }).BuildSessionFactory();
    

    I get this runtime error:

    An association from the table Metadata_AttachmentLocation refers to an unmapped class: System.Guid

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: NHibernate.MappingException: An association from the table Metadata_AttachmentLocation refers to an unmapped class: System.Guid

    Source Error:

    Line 19: Line 20: Line 21: SessionFactory = Fluently.Configure(configuration).Mappings(m => Line 22: { Line 23:
    m.FluentMappings.AddFromAssemblyOf();

    Source File: C:\Users\elad\Documents\Visual Studio 2010\Projects\SVN\UGI\Ugi\Infrastructure\Dal\Adapters\NHibernateAdapter\NHibernateHelper.cs Line: 21

    Stack Trace:

    [MappingException: An association from the table Metadata_AttachmentLocation refers to an unmapped class: System.Guid] NHibernate.Cfg.Configuration.LogAndThrow(Exception exception) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:342
    NHibernate.Cfg.Configuration.SecondPassCompileForeignKeys(Table table, ISet done) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:1169
    NHibernate.Cfg.Configuration.SecondPassCompile() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:1120
    NHibernate.Cfg.Configuration.BuildSessionFactory() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:1249
    FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:227

    [FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

    • Database was not configured through Database method. ]
      FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:232 Ugi.Infrastructure.Dal.Adapters.NHibernateAdapter.NHibernateHelper.OpenSession() in C:\Users\elad\Documents\Visual Studio 2010\Projects\SVN\UGI\Ugi\Infrastructure\Dal\Adapters\NHibernateAdapter\NHibernateHelper.cs:21 Ugi.Infrastructure.Dal.Adapters.NHibernateAdapter.NHibernateHelper.GetSession() in C:\Users\elad\Documents\Visual Studio 2010\Projects\SVN\UGI\Ugi\Infrastructure\Dal\Adapters\NHibernateAdapter\NHibernateHelper.cs:36 Ugi.Infrastructure.Dal.Adapters.NHibernateAdapter.NHibernateDal1..ctor() in C:\Users\elad\Documents\Visual Studio 2010\Projects\SVN\UGI\Ugi\Infrastructure\Dal\Adapters\NHibernateAdapter\NHibernateDal.cs:16 Ugi.Infrastructure.Dal.Adapters.NHibernateAdapter.NHibernateDalFactory.GetDal() in C:\Users\elad\Documents\Visual Studio 2010\Projects\SVN\UGI\Ugi\Infrastructure\Dal\Adapters\NHibernateAdapter\NHibernateDalFactory.cs:17 Ugi.Server.Sources.Logic.SourcesService..ctor() in C:\Users\elad\Documents\Visual Studio 2010\Projects\SVN\UGI\Ugi\Server\Sources\Logic\SourcesService.cs:36
      BuildUp_Ugi.Server.Sources.Logic.SourcesService(IBuilderContext ) +153 Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) in c:\EntLib\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlan.cs:37 Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in c:\EntLib\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:43 Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in c:\EntLib\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:110 Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable
      1 resolverOverrides) in c:\EntLib\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:512

    [ResolutionFailedException: Resolution of the dependency failed, type = "Ugi.Common.Model.Sources.ISourcesService", name = "(none)". Exception occurred while: Calling constructor Ugi.Server.Sources.Logic.SourcesService(). Exception is: FluentConfigurationException - An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

    • Database was not configured through Database method.

    How can I fix that?

    TIA

  • Elad Benda
    Elad Benda over 12 years
    How would it help? these two tables are bidirectional one-to-one relation. However in my code I need a reference only from AttachmentLocation to Attachment, and no visa versa.
  • Elad Benda
    Elad Benda over 12 years
    tried and got this exceptions:Error 1 The best overloaded method match for 'FluentNHibernate.Cfg.FluentConfiguration.Database(System.Fu‌​nc<FluentNHibernate.‌​Cfg.Db.IPersistenceC‌​onfigurer>)' has some invalid arguments and Error 2 Argument 1: cannot convert from 'NHibernate.Cfg.Configuration' to 'System.Func<FluentNHibernate.Cfg.Db.IPersistenceConfigurer>‌​'
  • Dave Rael
    Dave Rael over 12 years
    i wonder if we're using different versions of fluent nhibernate. i'm on 1.2.0.712. i see Database() with overloads for Func<IPersistenceConfigurer> and IPersistenceConfigurer. think should work with the latter of those.
  • Dave Rael
    Dave Rael over 12 years
    actually, looking at it again, i think your configuration object and mine are different. i am creating mine with:var configuration = MsSqlConfiguration.MsSql2008 .IsolationLevel(IsolationLevel.ReadCommitted) .ConnectionString(connectionString) .DefaultSchema(defaultSchema) .FormatSql(); this leads to a type of FluentNhibernate.Cfg.Db.MsSqlConfiguration (which has a base type of PersistenceConfiguration). looks like yours is coming from NHibernate instead of fluent. that must be there difference in using Configure with configuration vs Database().
  • Elad Benda
    Elad Benda over 12 years
    but I want to seperate between simple properties and contained foreign objects. Isn't that possible? These 3 primitive type compose compositeId. I don't want to reference all the 3 of them, only the PK of two of them and reference of the third. cann't I ?
  • Diego Mijelshon
    Diego Mijelshon over 12 years
    @EladBenda that's not the correct way to map relationships. You can always access Attachment.Id, which will give you the Attachment's id without the need for loading it from the DB.
  • Elad Benda
    Elad Benda over 12 years
    can you explain your last comment? How will Attachment.Id will be filled if the whole Attachment obj will not be filled from the DB?
  • Dave Rael
    Dave Rael over 12 years
    @elad - sorry, i didn't even look at your mapping. just saw the message about the Database method and went down a whole other path. diego is right about this, but i don't think cleaning this up will fix your problem. maybe i'm wrong about that, though. he's talking about lazy loading. referencing a mapped entity will load a dynamic proxy rather than the object itself. the proxy will return the id without loading the entire object. it's only if you access a property other than the id that nhibernate goes to the database to get the whole object.
  • Diego Mijelshon
    Diego Mijelshon over 12 years
    @EladBenda, @Dave is essentially right. That's how proxies work in NH, which enables the existence of the Load method, and one of the reasons why NH is more powerful than EF.
  • Maggie
    Maggie about 10 years
    This one seems to actually answer the OP's question.