实体框架核心.NET 7 7页£
#dotnet #database #oop #csharp

我想展示一个简单的示例,说明实体框架核心在.NET中的工作方式(本示例中特别是.NET 7)。实体框架是所谓的“对象相关映射器”(或简称ORM),它允许开发人员创建可以映射到数据库的类。

我已经建立了一个目录,其中包含有关足球运动员,球队,联赛和体育场的信息。该项目(可以找到here)是一个.NET核心项目,并使用剃须刀进行前端视图。

下面您可以看到已添加到目录中的所有播放器的列表,如果我为其中一位玩家选择“详细信息”,我可以查看更多信息(即,他们为哪个团队效力):

A preview of how players are listed within the application

A preview of how player information can be seen within the application

您可以看到玩家的Team Name与应用程序中的团队名称匹配:

A preview of how team information can be seen within the application

在我的数据库中,我想要为TeamsPlayersLeaguesStadiums的单独表

    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类包含TeamICollection。当我们创建具有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视图,例如:

  1. 右键单击您希望视图为
  2. 的文件夹上
  3. 悬停在“添加”上,然后选择“剃须刀页”
  4. 选择“使用实体框架(crud)”的“剃刀页”,然后点击“ add”
  5. 在出现的对话中,将“模型类”设置为要创建剃须刀页面的任何类
  6. 选择您的上下文类作为“ dbcontext类”,然后点击“ add”

Visual Studio将为您创建一些剃须页:

Showing how Razor Pages look within the Visual Studio solution

运行应用程序时,您将能够从数据库中查看所有行:

数据库
A preview of how the database tables look once created by Entity Framework

应用程序

A preview of how the database tables look when presented in the application

我只想简单地预览实体框架可以完成的操作,但是如果这让您感兴趣,并且您想对所有可能性进行更深入的研究,我建议您查看您的official docs。还可以找到一个很棒的tutorial,它将指导您构建自己的.NET核心Web应用程序。