需要一些关于NHibernate多对一关系的解释吗
您介意帮助我更好地理解如何处理我的实体和NHibernate之间的关系吗 我很难理解我需要手工做什么手术,以及NHibernate会为我做什么手术(或不做) 我有以下两个实体:需要一些关于NHibernate多对一关系的解释吗,nhibernate,one-to-many,relationship,Nhibernate,One To Many,Relationship,您介意帮助我更好地理解如何处理我的实体和NHibernate之间的关系吗 我很难理解我需要手工做什么手术,以及NHibernate会为我做什么手术(或不做) 我有以下两个实体: public class Position : BaseEntity<int, Position> { private IList<Player> allPlayers = new List<Player>(); public Position() {
public class Position : BaseEntity<int, Position>
{
private IList<Player> allPlayers = new List<Player>();
public Position()
{
}
public Position(string name, int number)
: this()
{
Name = name;
Number = number;
}
public string Name { get; set; }
public int Number { get; set; }
}
公共类位置:BaseEntity
{
私有IList allPlayers=新列表();
公共职位()
{
}
公共位置(字符串名称、整数)
:此()
{
名称=名称;
数字=数字;
}
公共字符串名称{get;set;}
公共整数{get;set;}
}
及
公共类玩家:BaseEntity
{
公共玩家()
{
可见=真实;
}
公共播放机(stringfirstname,stringlastname,int-defaultNumber,Sex-Sex=Sex.Male,positiondefaultposition=null)
:此()
{
名字=名字;
LastName=LastName;
DefaultNumber=DefaultNumber;
性别=性别;
DefaultPosition=DefaultPosition;
}
公共字符串名{get;set;}
公共字符串LastName{get;set;}
公共位置DefaultPosition{get;set;}
}
以下是fluent映射:
public class PositionMap : ClassMap<Position>
{
public PositionMap()
{
Id(pp => pp.Id)
.GeneratedBy.Increment();
Map(pp => pp.Name)
.Not.Nullable();
Map(pp => pp.Number)
.Not.Nullable();
HasMany<Player>(Reveal.Member<Position>("allPlayers"))
.Access.CamelCaseField();
}
}
public class PlayerMap : ClassMap<Player>
{
public PlayerMap()
{
Table("Players");
Id(p => p.Id)
.GeneratedBy.Increment();
Map(p => p.FirstName)
.Not.Nullable()
.UniqueKey("Players_Unique_FirstName_LastName");
Map(p => p.LastName)
.Not.Nullable()
.UniqueKey("Players_Unique_FirstName_LastName");
References(p => p.DefaultPosition);
}
}
公共类位置映射:类映射
{
公共位置图()
{
Id(pp=>pp.Id)
.GeneratedBy.Increment();
映射(pp=>pp.Name)
.Not.Nullable();
地图(pp=>pp.Number)
.Not.Nullable();
有很多(透露成员(“所有玩家”))
.Access.CamelCaseField();
}
}
公共类PlayerMap:ClassMap
{
公共播放器映射()
{
表(“玩家”);
Id(p=>p.Id)
.GeneratedBy.Increment();
映射(p=>p.FirstName)
.Not.Nullable()
.UniqueKey(“玩家\唯一\名\姓”);
映射(p=>p.LastName)
.Not.Nullable()
.UniqueKey(“玩家\唯一\名\姓”);
参考文献(p=>p.DefaultPosition);
}
}
正如您所看到的,一个玩家有一个位置,但可能没有位置(因此DefaultPosition可以为空)
以下是我的问题:
提前感谢Q1如果您为位置上的玩家添加属性,那么您就不需要这些辅助方法
public class Position : BaseEntity<int, Position>
{
private IList<Player> allPlayers = new List<Player>();
//read only
public IList<Player> Players { get { return allPlayers;} }
//... rest of class omitted
}
Q2、Q3您可以在位置上使用助手方法来简化
比如:
public class Position : BaseEntity<int, Position>
{
public void RemoveAll()
{
// null out the position on players
foreach(var player in allPlayers)
{
player.Position = null; // SETS PositionId FIELD IN PLAYER TABLE TO NULL
}
allPlayers.Clear();
}
// ... rest of class omitted
}
由于玩家将持续超过该位置,但该位置将被移除,因此您不希望使用cascade。级联用于删除,而不是真正更新id。例如,删除一个订单并级联它的所有行项目。那么,我应该如何用空位置ID更新数据库中的玩家?在会话中单独更新它们吗?或者使用HQL?RemoveAll函数清除实体之间的关系。但是,当我保存删除的位置时,NHibernate不会自动为每个有此位置的玩家的表玩家的字段PositionId设置NULL。我的问题也是如此。有没有办法强制NHibernate自动执行此操作,或者我应该添加一个自定义查询以在删除职位后执行此更新?我想我不知道该怎么说?上面的代码符合您的要求,为什么需要自定义查询?玩家是nhibernate对象,因此当他们的位置被设置为null并且事务被提交时,他们在db中的positionId将在该点为null。而position.Delete负责删除。因此,在这段代码的末尾,您将删除该位置,并且所有玩家的positionid将为null,这就是您所要求的。至于nhibernate,它不会自动这么做。正如帖子所说,Cascade是用于删除的,而不是空掉。我添加了一条注释,以强调示例中PositionID设置为空的位置。你不用猜,这是我的错。。。我忘了在我的代码中取消注释一行:/n现在,NHibernate确实会用NULL更新玩家的位置。无论如何,我还有一些问题:)我已经在PositionMap中的HasMany(pp=>pp.Players)上设置了反向。但如果我向该位置添加2名玩家,然后删除该位置,NHibernate会发出2个更新玩家的请求,而不是像这样的一个全局更新:updateplayers SET PositionId=NULL,其中PositionId=@p0;这是正常的行为吗?或者有没有办法强迫NHibernate只做一次更新?
var position = new Position();
position.Players.Add(new Player());
public class Position : BaseEntity<int, Position>
{
public void RemoveAll()
{
// null out the position on players
foreach(var player in allPlayers)
{
player.Position = null; // SETS PositionId FIELD IN PLAYER TABLE TO NULL
}
allPlayers.Clear();
}
// ... rest of class omitted
}
using(var session = SessionFactory.GetCurrentSession())
{
using(var tx = session.BeginTransaction())
{
position.RemoveAll();
position.Delete();
tx.Commit();
}
}