Fluent NHibernate code first 一对多

Fluent NHibernate code first One to Many

我开始学习 NHibernate,所以我正在尝试创建一些简单的关系 - 我正在尝试创建团队与球员和经理之间的关系 - 到目前为止我有 2 classes:

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

以及每个 class 地图:

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

从控制台输出来看,球队和经理之间的一对一关系似乎是正确的,但球队和球员之间的一对多关系不起作用 - 我的映射有什么想法class这些是错误的,或者我是如何插入它们的?

如果我们使用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 及其 Team;

// 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);