Fluent NHibernate复合ID表问题
本文关键字:问题 ID 复合 NHibernate Fluent | 更新日期: 2023-09-27 18:05:33
我有点不熟悉休眠,我遇到了一个问题。我有以下表格:
表1: 表名: Users,列1: ID,列2: Name
表2: 表名: 列1: ID,第二列:描述
表3: 表名: usertodomisations,列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);
}
}
用户地图:
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);
}
}
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();
}
}
我的问题是我不能保存新行。我可以选择并获取所有的东西,但不能保存。什么好主意吗?
谢谢。
编辑:我什么也得不到。不会抛出异常,但不会将行添加到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();
}
}
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();
}
}
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();
}
}
当我试图创建会话工厂时,我得到了异常:
{"无法在类'DatabaseEntities '中找到属性'UserIdPart'的getter。UserToDo"}
我在使用复合id时遇到过很多问题,比如下面这个。我建议像我之前做的那样创建一个新类型包含复合id所使用的id然后像这样映射:
CompositeId<UserToDoId>(x => x.ID)
.KeyReference(x => x.UserIdPart, c_userID)
.KeyReference(x => x.AchievementIdPart, c_missionID);
其中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;
}
}
}
我不知道为什么,但是当你不使用另一种类型来保存组件id的片段时,会出现一些小问题。
我有一个问题是在我的答案开头链接的。另一个我使用复合id的父抽象类与子类映射将尝试创建抽象类的实例(这是你不能做的)为某些查询。实现这个新类型解决了这两个问题。
试一试,看看是否有效。另外,"achievement"的拼写是"achievement"(不是要嘲弄你,我只是希望你能避免别人因为拼写错误而嘲笑你的代码:-D)