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);
我开始学习 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);