'How to map a collection of components as a set in fluent nhibernate
I want to map a collection of components on an entity. The component looks like this:
public class PermissionUserSetting
{
public virtual PermissionType PermissionType { get; set; }
public virtual string SettingName { get; set; }
public virtual CustomFieldInputType ValueType { get; set; }
public virtual string Value { get; set; }
public PermissionUserSetting(PermissionType permissionType, string settingName, CustomFieldInputType valueType, string value)
{
PermissionType = permissionType;
SettingName = settingName;
ValueType = valueType;
Value = value;
}
protected PermissionUserSetting()
{
}
}
These are unique across PermissionType and SettingName, so assuming in the database the PK would be OrganizationUserId, PermissionType, and SettingName.
This is on an entity OrganizationUser. For the mapping I have this:
mapping.HasMany(x => x.PermissionUserSettings)
.AsSet()
.KeyColumn("OrganizationUserId")
//.KeyColumns.Add("PermissionType", "SettingName") THIS DOESN'T WORK!
.Component(part =>
{
part.Map(x => x.PermissionType);
part.Map(x => x.SettingName);
part.Map(x => x.ValueType);
part.Map(x => x.Value);
});
I'm getting an error: - InnerException {"Foreign key (FK23A9E495A0C2E98C:PermissionUserSettings [OrganizationUserId, PermissionType, SettingName])) must have same number of columns as the referenced primary key (OrganizationUser [Id])"} System.Exception {NHibernate.FKUnmatchingColumnsException}
How do I get this mapped?
Solution 1:[1]
You need to declare a composite id with Fluent NHibernate. This is how to do
public class PermissionUserSettingMap : ClassMap<PermissionUserSetting>
{
public EntityMap()
{
CompositeId()
.KeyProperty(x => x.OrganizationUserId)
.KeyReference(x => x.PermissionType) // assuming PermissionType is a Reference type
.KeyProperty(x => x.SettingName);
Map(x => x.ValueType);
Map(x => x.Value);
}
}
To use a composite Id your entity must override bool Equals(object obj) and int GetHashCode()
public class PermissionUserSetting
{
public virtual int OrganizationUserId { get; set; } // you must declare all part of your composite key
public virtual PermissionType PermissionType { get; set; }
public virtual string SettingName { get; set; }
public virtual CustomFieldInputType ValueType { get; set; }
public virtual string Value { get; set; }
public override bool Equals(object obj) =>
obj is PermissionUserSetting pus &&
OrganizationUserId == pus.OrganizationUserId &&
PermissionType == pus.PermissionType &&
SettingName == pus.SettingName);
public override int GetHashCode() =>
OrganizationUserId.GetHashCode() ^
PermissionType.GetHashCode() ^
SettingName.GetHashCode();
}
Its always better to have a single primary key for Nhibernate with a unique constraint than a Composite Id
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Orkad |
