流畅的NHibernate复合ID表问题

Ben*_*Ben 2 c# nhibernate composite save fluent-nhibernate

我对nhibernate有点新,我遇到了一个问题.我有以下表格:

表1: 表名:用户, 第1列: ID, 第2列:名称

表2: 表名:任务, 第1列: ID, 第2列:描述

表3: 表名: UserToDoMissions,第1列: UserID, 第2 : MissionID , 第3列:排名

这是代码:MissionMap:

public class MissionMap : ClassMap<Mission>
{
    public const string TableName = "tblMissions";
    public const string c_id = "achID";
    public const string c_name = "achName";

    public MissionMap()
    {
        Table(TableName);
        Id(x => x.ID).Column(c_id).Not.Nullable();
        Map(x => x.Name).Column(c_name).Not.Nullable();

        HasMany(x => x.UserToDoList).Cascade.All().Inverse().KeyColumn(UserToDoMap.c_missionID);
    }
}
Run Code Online (Sandbox Code Playgroud)

用户地图:

public class UserMap : ClassMap<User>
{
    public const string TableName = "tblUsers";
    public const string c_id = "usrID";
    public const string c_userName = "usrUserName";

    public UserMap()
    {
        Table(TableName);
        Id(x => x.ID).Column(c_id).Not.Nullable();
        Map(x => x.UserName).Column(c_userName).UniqueKey(DBConsts.UniqueKeys.User_UserName).Not.Nullable();

        HasMany(x => x.UserToDoList).Cascade.All().Inverse().KeyColumn(UserToDoMap.c_userID);
    }
}
Run Code Online (Sandbox Code Playgroud)

UserToDo地图:

public class UserToDoMap : ClassMap<UserToDo>
{
    public const string TableName = "tblToDoList";
    public const string c_userID = "tdlUserID";
    public const string c_missionID = "tdlMissionID";
    public const string c_rank = "tdlRank";

    public UserToDoMap()
    {
        Table(TableName);
        CompositeId().KeyReference(x => x.User, c_userID).KeyReference(x => x.Achievment, c_missionID);
        References(x => x.User).Column(c_userID).Cascade.All().UniqueKey(DBConsts.UniqueKeys.ToDoList_UserRanks).Not.Nullable();
        References(x => x.Mission).Column(c_missionID).Cascade.All().Not.Nullable();
        Map(x => x.Rank).Column(c_rank).UniqueKey(DBConsts.UniqueKeys.ToDoList_UserRanks).Not.Nullable();
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是我可以保存一条新线.我可以选择并获得所有的东西,但无法保存.有任何想法吗?

谢谢.

编辑:我什么都没得到.没有抛出异常,但该行未添加到DB.顺便说一句,我在UserToDo对象上使用了save方法.

编辑2:在docmanhattan回答这里是代码:

UserToDoMap:

public class UserToDoMap : ClassMap<UserToDo>
{
    public const string TableName = "tblToDoList";
    public const string c_userID = "tdlUserID";
    public const string c_missionID = "tdlMissionID";
    public const string c_rank = "tdlRank";

    public UserToDoMap()
    {
        Table(TableName);
        CompositeId<UserToDoId>(x => x.ID)
            .KeyReference(x => x.UserIdPart, c_userID)
            .KeyReference(x => x.MissionIdPart, c_missionID);
        References(x => x.ID.UserIdPart).Column(c_userID).Cascade.All().UniqueKey(DBConsts.UniqueKeys.ToDoList_UserRanks).Not.Nullable();
        References(x => x.ID.MissionIdPart).Column(c_missionID).Cascade.All().Not.Nullable();
        Map(x => x.Rank).Column(c_rank).UniqueKey(DBConsts.UniqueKeys.ToDoList_UserRanks).Not.Nullable();
    }
}
Run Code Online (Sandbox Code Playgroud)

UserToDoId实体:

public class UserToDoId
{
    public virtual User UserIdPart { get; set; }
    public virtual Mission MissionIdPart { get; set; }

    public override bool Equals(object obj)
    {
        UserToDoId recievedObject = (UserToDoId)obj;

        if ((UserIdPart.ID == recievedObject.UserIdPart.ID) &&
            (MissionIdPart.ID == recievedObject.MissionIdPart.ID))
        {
            return (true);
        }

        return (false);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

UserToDo实体:

public class UserToDo
{
    public virtual UserToDoId ID { get; set; }

    public virtual int Rank { get; set; }

    public UserToDo()
    {

    }

    public override bool Equals(object obj)
    {
        UserToDo recievedObject = (UserToDo)obj;

        if ((ID.UserIdPart.ID == recievedObject.ID.UserIdPart.ID) &&
            (ID.MissionIdPart.ID == recievedObject.ID.MissionIdPart.ID) &&
            (Rank == recievedObject.Rank))
        {
            return (true);
        }

        return (false);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建会话工厂时遇到异常:

{"在"DatabaseEntities.UserToDo"类中找不到属性'UserIdPart'的getter'}}

doc*_*tan 5

使用复合id进行处理时遇到了很多问题,比如这个问题.我建议我做的是创建一个新类型,它只包含复合id用于id的内容,然后映射它:

CompositeId<UserToDoId>(x => x.ID)
    .KeyReference(x => x.UserIdPart, c_userID)
    .KeyReference(x => x.AchievementIdPart, c_missionID);
Run Code Online (Sandbox Code Playgroud)

UserToDoId具有复合id中使用的两个引用:

public class UserToDoId
{
    User UserIdPart { get; set; }
    Achievement AchievementIdPart { get; set; }

    public override bool Equals(object obj)
    {
        return Equals(obj as UserToDoId);
    }

    private bool Equals(UserToDoId other)
    {
        if (ReferenceEquals(other, null)) return false;
        if (ReferenceEquals(other, this)) return true;

        return UserIdPart.ID == other.UserIdPart.ID &&
            MissionIdPart.ID == other.MissionIdPart.ID;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = GetType().GetHashCode();
            hash = (hash * 31) ^ UserIdPart.ID.GetHashCode();
            hash = (hash * 31) ^ MissionIdPart.ID.GetHashCode();

            return hash;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么,但是当你不使用另一种类型来保存组件id的部分时,会弹出一堆小问题.

我的一个问题在一开始就与我的答案联系在一起.我使用的另一个是使用复合id作为具有子类映射的父抽象类,它将尝试为某些查询创建抽象类的实例(您不能这样做).实现这种新类型解决了这两个问题.

试一试,看看是否有效.此外,'成就'拼写为"成就"(不是试图嘲讽,我只是希望你能避免人们在你的代码中嘲笑拼写错误:-D)