0

I am having a real problem with NHibernate Mapping By Code and a Composite Key in one of my classes.

The Domain class is as follows:-

    public partial class UserRole {
    public virtual int UserId { get; set; }
    public virtual int RoleId { get; set; }
    //public virtual UserRoleId Id { get; set; }
    public virtual User User { get; set; }
    public virtual Role Role { get; set; }
    [NotNullNotEmpty]
    public virtual DateTime VqsCreateDate { get; set; }
    public virtual DateTime? VqsUpdateDate { get; set; }
    [NotNullNotEmpty]
    public virtual bool VqsMarkedForDelete { get; set; }
    [Length(50)]
    public virtual string VqsCreateUserName { get; set; }
    [Length(50)]
    public virtual string VqsLastUpdatedUserName { get; set; }
    [NotNullNotEmpty]
    [Length(128)]
    public virtual string VqsCreateSessionId { get; set; }
    [Length(128)]
    public virtual string VqsLastUpdatedSessionId { get; set; }
    [NotNullNotEmpty]
    [Length(15)]
    public virtual string VqsCreateIpAddress { get; set; }
    [Length(15)]
    public virtual string VqsLastUpdatedIpAddress { get; set; }
    [Length(255)]
    public virtual string VqsCreateSessionInfo { get; set; }
    [Length(255)]
    public virtual string VqsLastUpdatedSessionInfo { get; set; }
    [NotNullNotEmpty]
    public virtual bool VqsAllowDelete { get; set; }
    public virtual bool? VqsAllowEdit { get; set; }
    [Length(50)]
    public virtual string VqsRffu1 { get; set; }
    [Length(50)]
    public virtual string VqsRffu2 { get; set; }
    [Length(50)]
    public virtual string VqsRffu3 { get; set; }
    #region NHibernate Composite Key Requirements
    public override bool Equals(object obj) {
        if (obj == null) return false;
        var t = obj as UserRole;
        if (t == null) return false;
        if (UserId == t.UserId
         && RoleId == t.RoleId)
            return true;

        return false;
    }
    public override int GetHashCode() {
        int hash = GetType().GetHashCode();
        hash = (hash * 397) ^ UserId.GetHashCode();
        hash = (hash * 397) ^ RoleId.GetHashCode();

        return hash;
    }
    #endregion
}

And the mapping class is as follows:-

   public partial class UserRoleMap : ClassMapping<UserRole> {

    public UserRoleMap() {
        Schema("Membership");
        Lazy(true);
        ComposedId(compId =>
            {
                compId.Property(x => x.UserId, m => m.Column("UserId"));
                compId.Property(x => x.RoleId, m => m.Column("RoleId"));
            });
        Property(x => x.VqsCreateDate, map => map.NotNullable(true));
        Property(x => x.VqsUpdateDate);
        Property(x => x.VqsMarkedForDelete, map => map.NotNullable(true));
        Property(x => x.VqsCreateUserName, map => map.Length(50));
        Property(x => x.VqsLastUpdatedUserName, map => map.Length(50));
        Property(x => x.VqsCreateSessionId, map => { map.NotNullable(true); map.Length(128); });
        Property(x => x.VqsLastUpdatedSessionId, map => map.Length(128));
        Property(x => x.VqsCreateIpAddress, map => { map.NotNullable(true); map.Length(15); });
        Property(x => x.VqsLastUpdatedIpAddress, map => map.Length(15));
        Property(x => x.VqsCreateSessionInfo, map => map.Length(255));
        Property(x => x.VqsLastUpdatedSessionInfo, map => map.Length(255));
        Property(x => x.VqsAllowDelete, map => map.NotNullable(true));
        Property(x => x.VqsAllowEdit);
        Property(x => x.VqsRffu1, map => map.Length(50));
        Property(x => x.VqsRffu2, map => map.Length(50));
        Property(x => x.VqsRffu3, map => map.Length(50));
        ManyToOne(x => x.User, map =>
        {
            map.Column("UserId");
            ////map.PropertyRef("Id");
            map.Cascade(Cascade.None);
        });

        ManyToOne(x => x.Role, map =>
        {
            map.Column("RoleId");
            ////map.PropertyRef("Id");
            map.Cascade(Cascade.None);
        });

    }
}

Whenever I try to insert into this table I get the following error:-

Invalid index for this SqlParameterCollection with Count 'N'

I have looked at all the occurrences of this error on StackExchange and across the majority of the internet for the last day and am still no further on.

There seem to be a lot of examples for Xml and Fluent mapping, but very little for Mapping By Code.

I think I have tried every combination of suggestions, but all to no avail.

I am fully aware that the problem is related to the fact that I have the ID fields in the table referenced twice and this is ultimately causing the error,

The problem is that I need both the ID and Entity Fields in my class as they are used extensively throughout the code.

I seem to be experiencing the issue as I have the combination of a composite and foreign keys in my many to many table.

Any help that anyone could provide to preserve my sanity would be very much appreciated.

Many thanks in advance.

Simon

1 Answer 1

1

You can set Insert(false) and Update(false) to prevent Nhibernate from generating an update or insert statement which includes the User and Role columns (which do not exist).

        ManyToOne(x => x.User, map =>
        {
            map.Column("UserId");
            ////map.PropertyRef("Id");
            map.Cascade(Cascade.None);
            map.Insert(false);
            map.Update(false);
        });

        ManyToOne(x => x.Role, map =>
        {
            map.Column("RoleId");
            ////map.PropertyRef("Id");
            map.Cascade(Cascade.None);
            map.Insert(false);
            map.Update(false);
        });

That's the same as Not.Update() Not.Insert() in Fluent mapping.

If you now create a valid UserRole object and set bot IDs to valid user/role ID NHibernate should be able to persist your object.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much. Sometimes, I spend so much time looking at something, I just cant see the wood for the trees. This is the first time I have ever posted on StackExchange, and cant believe how quick you responded. It is very much apprerciated.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.