Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
需要一些关于NHibernate多对一关系的解释吗_Nhibernate_One To Many_Relationship - Fatal编程技术网

需要一些关于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() {

您介意帮助我更好地理解如何处理我的实体和NHibernate之间的关系吗

我很难理解我需要手工做什么手术,以及NHibernate会为我做什么手术(或不做)

我有以下两个实体:

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可以为空)

以下是我的问题:

  • 当我将一个位置关联到一个玩家的默认位置时,我必须通过position上的helper方法来实现这一点?(如AddPlayer、DeletePlayer…)
  • 我希望,当我删除一个位置时,所有拥有这个位置的玩家都有一个空的默认位置

  • 我是否必须手动清除该位置的AllPlayer字段,并手动将空值设置为所有关联玩家的DefaultPosition,或者NHibernate是否可以为我处理此问题

  • 为什么NHibernate只从Id。。。不更新相关球员的场地位置吗?我尝试在HasMany in-PositionMap上添加一个Cascade.Delete,但这并没有改变任何事情。我是否必须运行一个自定义查询来实现这一点


  • 提前感谢

    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();
       }
    }