Fluent NHibernate代码第一个一对多

本文关键字:一对多 第一个 代码 NHibernate Fluent | 更新日期: 2023-09-27 18:25:43

我开始学习NHibernate,所以我试图创建一些简单的关系-我试图创建团队和球员之间的关系&经理-到目前为止,我有两个班:

public class Person
{
    public virtual int PersonId { get; set; }
    public virtual Team Team { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
    public virtual PersonType PersonType { get; set; } = PersonType.Player;
}
public enum PersonType
{
    Player = 1,
    Manager = 2,
    Referee = 3
}
public class Team
{
    public virtual int TeamId { get; set; }
    public virtual int Ranking { get; set; }
    public virtual IList<Person> Players { get; set; } = new List<Person>();
    public virtual Person Manager { get; set; }
}

以及每个的类映射:

public class PersonMap : ClassMap<Person>
{
    public PersonMap()
    {
        Id(x => x.PersonId);
        References(x => x.Team).Cascade.None();
        Map(x => x.FirstName);
        Map(x => x.LastName);
        Map(x => x.PersonType).CustomType<PersonType>(); // register the enum as a custom type, otherwise it will be mapped as a string
    }
}
public class TeamMap : ClassMap<Team>
{
    public TeamMap()
    {
        Id(x => x.TeamId);
        Map(x => x.Ranking);
        HasMany(x => x.Players).Inverse().Cascade.All(); // any changes that are made to the team are cascaded to the players
        References(x => x.Manager).Cascade.None();
    }
}

当我在控制台应用程序中运行以下代码时

class Program
{
    static void Main(string[] args)
    {
        // pull a connection string from the config file
        var connectionString = ConfigurationManager.ConnectionStrings["Bonkers"].ConnectionString;
        // build a configuration object
        var configuration = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2012.ConnectionString(connectionString))
            .Mappings(m => m.FluentMappings
            .AddFromAssemblyOf<PersonMap>()
            .AddFromAssemblyOf<TeamMap>())
            .BuildConfiguration();
        // export the schema configuration
        var exporter = new SchemaExport(configuration);
        exporter.Execute(true, true, false);
        // create a session factory
        var sessionFactory = configuration.BuildSessionFactory();
        // open a new session and add a new customer
        using (var session = sessionFactory.OpenSession())
        {
            var manager = new Person { FirstName = "Chris", PersonType = PersonType.Manager };
            var players = new List<Person>()
            {
                manager,
                new Person { FirstName = "Mark", PersonType = PersonType.Player },
                new Person { FirstName = "Karl", PersonType = PersonType.Player }
            };
            players.ForEach(player => session.Save(player)); // save all the players (& manager)
            var team = new Team { Ranking = 1, Manager = manager, Players = players.Where(p => p.PersonType != PersonType.Manager).ToList() };
            players.ForEach(player => session.Save(player)); // save all the players (& manager)
            session.Save(team); // save the team (the players should now exist in there)
        }
        // using a session query the database and update the customer type
        using (var session = sessionFactory.OpenSession())
        {
            using (var transaction = session.BeginTransaction())
            {
                session.Query<Team>().ToList().ForEach(team => 
                {
                    WriteLine($"Manager: {team.Manager.FirstName} Ranking: {team.Ranking}");
                    WriteLine($"Team players:");
                    team.Players.ToList().ForEach(p => WriteLine($"- {p.FirstName} {p.PersonType}"));
                });
                WriteLine($"Players:");
                session.Query<Person>().ToList()
                    .ForEach(c => WriteLine($"- {c.FirstName} {c.LastName} {c.PersonId} {c.Team?.TeamId} {c.PersonType}"));
            }
        }
        ReadKey();
    }
}

从控制台输出来看,团队和经理之间的一对一关系似乎是正确的,但团队和球员之间的一比多关系不起作用——有没有想过我的映射类哪里错了,或者我是如何插入它们的?

Fluent NHibernate代码第一个一对多

如果我们使用Inverse(),即使在代码中也必须进行反向映射,即在两侧设置双向关系。

// this is wrong, we do not provide inverse relation
var players = new List<Person>()
{
    manager,
    new Person { FirstName = "Mark", PersonType = PersonType.Player },
    new Person { FirstName = "Karl", PersonType = PersonType.Player }
};

上述代码未向Person提供其团队;

// this is wrong, we do not provide inverse relation
var team = new Team { ... };
var p1 = new Person { FirstName = "Mark", PersonType = PersonType.Player };
var p2 = new Person { FirstName = "Karl", PersonType = PersonType.Player };
// the inverse relation is a MUST
p1.Team = team;
p2.Team = team;
// this will do the cascade
team.Players.Add(p1);
team.Players.Add(p2);
// now only team could be saved, the rest will be done by cascades
session.Save(team);