我想展示一个简单的示例,说明实体框架核心在.NET中的工作方式(本示例中特别是.NET 7)。实体框架是所谓的“对象相关映射器”(或简称ORM),它允许开发人员创建可以映射到数据库的类。
我已经建立了一个目录,其中包含有关足球运动员,球队,联赛和体育场的信息。该项目(可以找到here)是一个.NET核心项目,并使用剃须刀进行前端视图。
下面您可以看到已添加到目录中的所有播放器的列表,如果我为其中一位玩家选择“详细信息”,我可以查看更多信息(即,他们为哪个团队效力):
您可以看到玩家的Team Name
与应用程序中的团队名称匹配:
在我的数据库中,我想要为Teams
,Players
,Leagues
和Stadiums
的单独表
public class Team
{
public int TeamID { get; set; }
public string Name { get; set; }
public int LeagueID { get; set; }
public League League { get; set; }
public int StadiumID { get; set; }
public ICollection<Player> Players { get; set;}
}
public class Player
{
public int PlayerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int TeamID { get; set; }
public PlayerPosition Position { get; set; }
}
public class League
{
public int LeagueID { get; set; }
public ICollection<Team> Teams { get; set; }
public int NumberOfTeams { get; set; }
public string Name { get; set; }
}
public class Stadium
{
public int StadiumID { get; set; }
public int TeamID { get; set; }
public int Capacity { get; set; }
public string Name { get; set; }
}
这些表的关系如下:
-
一个
Team
可以拥有许多Players
-
一个
Team
有一个Stadium
-
一个
League
有许多Stadiums
每个类都有一个ID属性(这将代表数据库中的主要密钥)。有些类也具有另一种类型的ID(例如,Stadium
类具有TeamID
的ID)。这代表数据库中的外键。另外,您会注意到Team
类是如何包含Player
类型的ICollection
,而League
类包含Team
的ICollection
。当我们创建具有ICollection的类时,该表将在数据库中表示为一对多关系。
我还创建了一个包含种子数据的单独类,因此第一次运行应用程序后,我们将在数据库中拥有初始数据:
public static class DbInitializer
{
public static void Initialize(TeamContext context)
{
if (context.Teams.Any())
{
return;
}
var leagues = new League[]
{
new League{Name="Ligue 1",NumberOfTeams=20},
new League{Name="English Premier League",NumberOfTeams=20},
new League{Name="La Liga",NumberOfTeams=20},
new League{Name="Serie A",NumberOfTeams=20},
new League{Name="Bundesliga",NumberOfTeams=18}
};
context.Leagues.AddRange(leagues);
context.SaveChanges();
var teams = new Team[]
{
new Team{Name="Paris Saint Germain",LeagueID=1,StadiumID=1},
new Team{Name="Tottenham Hotspur",LeagueID=2,StadiumID=2},
new Team{Name="Real Madrid",LeagueID=3,StadiumID=3},
new Team{Name="AC Milan",LeagueID=4,StadiumID=4},
new Team{Name="Bayern Munich",LeagueID=5,StadiumID=5},
new Team{Name="Chelsea",LeagueID=2,StadiumID=6},
new Team{Name="Internazionale",LeagueID=4,StadiumID=4}
};
context.Teams.AddRange(teams);
context.SaveChanges();
var players = new Player[]
{
new Player{FirstName="Lionel",LastName="Messi",TeamID=1,Position=PlayerPosition.Midfielder},
new Player{FirstName="Harry",LastName="Kane",TeamID=2,Position=PlayerPosition.Forward},
new Player{FirstName="Vinicius",LastName="Jr",TeamID=3,Position=PlayerPosition.Forward},
new Player{FirstName="Rafael",LastName="Leao",TeamID=4,Position=PlayerPosition.Forward},
new Player{FirstName="Joshua",LastName="Kimmich",TeamID=5,Position=PlayerPosition.Defender},
new Player{FirstName="Enzo",LastName="Fernandez",TeamID=6,Position=PlayerPosition.Midfielder},
new Player{FirstName="Lautaro",LastName="Martinez",TeamID=7,Position=PlayerPosition.Forward}
};
context.Players.AddRange(players);
context.SaveChanges();
var stadiums = new Stadium[]
{
new Stadium{Name="Parc de Princes",TeamID=1,Capacity=50000},
new Stadium{Name="Tottenham Hotspur Stadium",TeamID=2,Capacity=60000},
new Stadium{Name="Santiago Bernabeu Stadium",TeamID=3,Capacity=80000},
new Stadium{Name="San Siro",TeamID=4,Capacity=75000},
new Stadium{Name="Aliianz Arena",TeamID=5,Capacity=75000},
new Stadium{Name="Stamford Bridge",TeamID=6,Capacity=40000}
};
context.Stadiums.AddRange(stadiums);
context.SaveChanges();
}
}
运行了Initialize()
方法后,您可以首先查看它填充了context.Teams
,如果不是,则(即,如果这是我们第一次运行应用程序),则会创建多个对象并将其保存到数据库中。 TeamContext
类是一个从实体框架的DbContext
类继承的类,用于定义我们希望如何设置数据库。您可以设置应该创建哪些表(DbSet
)的类别(DbSet
),任何类别和任何时间都需要更新数据库,我们可以访问此对象(例如,在上面的DbInitializer
中,我们添加到列表中,然后调用context.SaveChanges()
来保存数据库的这些更改。)
public class TeamContext : DbContext
{
public TeamContext (DbContextOptions<TeamContext> options)
: base(options)
{
}
public DbSet<Team> Teams { get; set; }
public DbSet<Player> Players { get; set; }
public DbSet<League> Leagues { get; set; }
public DbSet<Stadium> Stadiums { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Team>().ToTable("Team");
modelBuilder.Entity<Player>().ToTable("Player");
modelBuilder.Entity<League>().ToTable("League");
modelBuilder.Entity<Stadium>().ToTable("Stadium");
}
}
如前所述,我们正在使用Razor Pages进行视图。 .NET使创建,读取,更新和删除实体的创建视图确实很容易。我最初为Visual Studio中的玩家实体创建了Razor视图,例如:
- 右键单击您希望视图为 的文件夹上
- 悬停在“添加”上,然后选择“剃须刀页”
- 选择“使用实体框架(crud)”的“剃刀页”,然后点击“ add”
- 在出现的对话中,将“模型类”设置为要创建剃须刀页面的任何类
- 选择您的上下文类作为“ dbcontext类”,然后点击“ add”
Visual Studio将为您创建一些剃须页:
运行应用程序时,您将能够从数据库中查看所有行:
应用程序:
我只想简单地预览实体框架可以完成的操作,但是如果这让您感兴趣,并且您想对所有可能性进行更深入的研究,我建议您查看您的official docs。还可以找到一个很棒的tutorial,它将指导您构建自己的.NET核心Web应用程序。