NH 3.3 Composite-ID mapping by code
Asked Answered
A

3

5

Diagram

I am pulling my hair out here trying to figure out how to map the UsersRoles table listed below. I don't look good bald so please help :)

//Here is the Entity

public class UsersRole
{
    public UsersRole() { }
    public virtual User User { get; set; }
    public virtual Role Role { get; set; }
    public virtual System.Guid UserId { get; set; }
    public virtual System.Guid RoleId { get; set; }


}

//Here is the mapping so far

public class UsersRoleMap : ClassMapping<UsersRole>
{
    public UsersRoleMap()
    {
        Table("UsersRoles");
        Lazy(true);

       // ComponentAsId(); How does this work??


        Property(x => x.UserId, map => map.Column(c =>
            {
                c.Name("UserId");
                c.NotNullable(true);
                c.Length(30);
                c.SqlType("uniqueidentifier");
            }));
        Property(x => x.RoleId, map => map.Column(c =>
            {
                c.Name("RoleId");
                c.NotNullable(true);
                c.Length(30);
                c.SqlType("uniqueidentifier");
            }));
    }
}

Please see the comment in the mapping for ComponentAsId

Thanks in advance if someone can get me on the right track

Ascites answered 1/8, 2012 at 15:55 Comment(0)
T
6

The method you are looking for is called ComposedId:

public class UsersRoleMap : ClassMapping<UsersRole>
{
    public UsersRoleMap()
    {
        ComposedId(map => 
        {
            map.Property(x => x.UserId);
            map.Property(x => x.RoleId);
        });
    }
}

Answering to your question about how ComponentAsId works. You should have following classes to use ComponentAsId method

public class UsersRoleId
{
    public System.Guid UserId { get; set; }
    public System.Guid RoleId { get; set; }
}

public class UsersRole
{
    public virtual User User { get; set; }
    public virtual Role Role { get; set; }
    public virtual UsersRoleId Id { get; set; }
}

And now you could map UsersRole.Id as ComponentAsId

public class UsersRoleMap : ClassMapping<UsersRole>
{
    public UsersRoleMap()
    {
        ComponentAsId(x => x.Id);
    }
}

PS: Why you need to map UsersRoles table? I would suggest you to map users to roles as many-to-many relation.

public class UsersMap : ClassMapping<User>
{
    public UsersMap()
    {
        Set(x => x.Roles, x => { }, x => x.ManyToMany());
    }
}

public class RolesMap : ClassMapping<Role>
{
    public RolesMap()
    {
        Set(x => x.Users, x => { }, x => x.ManyToMany());
    }
}
Taynatayra answered 1/8, 2012 at 16:15 Comment(3)
Excellent sir. Thanks for the info. I will map as a many-to-many. Yes you are correct on the composite-id, I really don't need to map the usersroles table as an entity. Thanks for the example on the ComponentAsId as well.Ascites
This is still not working for me. I get Foreign key (FK5F7A4833608B61EC:Roles [elt])) must have same number of columns as the referenced primary key (Roles [user_key, elt])Ascites
I am pretty sure it's meant to be ComposedId not CompositeId. notherdev.blogspot.com.au/2012/02/…Hubsher
C
1

Do you really need to have UsersRole as an entity? Usually, you only create a many-to-many entity when you have some additional columns in database table, apart from two ids.

Besides, even when you need to create a separate entity, you don't need to have UserId and RoleId properties. Having User and Role properties is enough to map with NHibernate.

Take a look at many-to-many mapping instead and define your User entity like this:

public class User
{
    // other properties
    public virtual IList<Role> Roles { get; set; }
}

Now you can map that Role property using ManyToMany mapping:

Bag(x => x.Roles, collectionMapping =>
{
    collectionMapping.Table("UsersRole");
    collectionMapping.Key(k => k.Column("RoleId"));
}, map => map.ManyToMany(p => p.Column("UserId")));

Here's one more example.

Cence answered 1/8, 2012 at 16:13 Comment(0)
H
0

The following are two ways you can implement the mapping for a composite key with NHibernate Mapping-By-Code.

ComponentAsId(x => x.Key, m =>
{
    m.Property(x => x.KeyPart);
    // etc.
});

ComposedId(m =>
{
    m.Property(x => x.KeyPart);
    // other key parts
});
Hubsher answered 13/9, 2013 at 0:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.