码字,杂谈

.net core 3.x使用mysql EntityFramework

本文演示了MySql Entityframework在.net core中的基本使用。

添加依赖包

使用NuGet添加依赖,全部使用最新的即可。

Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.Design
Microsoft.EntityFrameworkCore.Tools
MySql.Data.EntityFrameworkCore
Plmelo.EntityFrameworkCore.MySql

安装后,就可以添加代码了。

添加连接

appsettings.json中添加如下代码:

"ConnectionStrings": {
    "Database": "Server=192.168.1.22;User Id=jeremyjone;Password=123456;Database=db;"
}

这里注意,需要将所有参数换成自己的正确参数。如果数据库不是本地的,一般情况下是不能用root用户的,需要注意。

创建实体

这里需要注意,此操作是基于数据库已经创建好的情况,一般情况下,我也更推荐这种做法,数据库在初期就已经创建好,不需要进行来回变动。

我的测试数据库中有一个company表:

《.net core 3.x使用mysql EntityFramework》

在程序包管理器控制台(工具 -> NuGet包管理器 -> 程序包管理器控制台,或者使用快捷键 ctrl + `)中输入下面的命令。

Scaffold-DbContext "Server=192.168.1.22;User Id=jeremyjone;Password=123456;Database=db;" "Pomelo.EntityFrameworkCore.MySql" -OutputDir Models -force

其中,-OutPutDir表示生成的类放在哪个文件夹,-force表示如果文件夹中有同名文件,替换之。

输入后确定,会直接创建出对应的实体模型和数据库上下文。

《.net core 3.x使用mysql EntityFramework》

《.net core 3.x使用mysql EntityFramework》

包括下面的OnModelCreateing函数,完全不用我们手写,只需要稍加整理后,我们就可以直接使用了。

注入数据库上下文

打开Startup.cs文件,首先添加一个构造函数,将IConfiguration注入:

public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

然后在ConfigureServices函数中,注入数据库上下文:

// 首先取出appsettings中的连接字符串,注意参数名应与appsettings中键一致
var connectionString = Configuration.GetConnectionString("Database");
// 类型是生成的上下文类名
services.AddDbContext<MyDbContext>(options => options.UseMySql(connectionString));

此时已经可以正常访问数据库了,不过下面还要配置一个用于操作的仓库

配置仓库并注入

创建一个名为Repositories的文件夹,并在该文件夹下创建一个对应的操作接口,我的测试数据库有一个Company表,所以我创建了一个ICompanyRepository.cs接口:

public interface ICompanyRepository
{
    Task<IEnumerable<Company>> GetCompaniesAsync();
    Task<Company> GetCompanyAsync(int companyId);
    void AddCompany(Company company);
    Task<bool> SaveAsync();
}

然后Alt + Enter直接生成实现类,并将其移动到新文件CompanyRepository.cs中:

class CompanyRepository : ICompanyRepository
{
    private readonly MyDbContext _myDbContext;

    public CompanyRepository(MyDbContext myDbContext)
    {
        _myDbContext = myDbContext ?? throw new ArgumentNullException(nameof(myDbContext));
    }
    public async Task<IEnumerable<Company>> GetCompaniesAsync()
    {
        return await _myDbContext.Companies.ToArrayAsync();
    }

    public async Task<Company> GetCompanyAsync(int companyId)
    {
        return await _myDbContext.Companies.FirstOrDefaultAsync(x => x.Id == companyId);
    }

    public void AddCompany(Company company)
    {
        _myDbContext.Companies.Add(company);
    }

    public async Task<bool> SaveAsync()
    {
        return await _myDbContext.SaveChangesAsync() >= 0;
    }
}

这里只是简单测试一下主要功能,所以添加一个Get和一个Post即可。

最后将仓库注入,转到Startup.cs文件中,添加注入:

services.AddScoped<ICompanyRepository, CompanyRepository>();

数据库的服务应该是以每一个HTTP请求为请求周期的,所以使用Scoped。当然,使用其他方法也可以。

创建控制器

最后就是创建控制器。

添加一个名为Controllers的文件夹,并创建一个CompaniesController.cs文件,实现三个方法:一个获取全部,一个获取单个,一个提交:

[ApiController]
[Route("api/companies")]
public class CompaniesController : ControllerBase
{
    private readonly ICompanyRepository _companyRepository;

    // 注入ComponanyRepository,就可以直接在控制器中使用其方法了
    public CompaniesController(ICompanyRepository companyRepository)
    {
        _companyRepository = companyRepository;
    }

    [HttpGet]
    public async Task<ActionResult<IEnumerable<Company>>> GetCompanies()
    {
        var companies = await _companyRepository.GetCompaniesAsync();
        return Ok(companies);
    }

    [HttpGet]
    [Route("{companyId}", Name = nameof(GetCompany))]
    public async Task<ActionResult<IEnumerable<Company>>> GetCompany(int companyId)
    {
        var company = await _companyRepository.GetCompanyAsync(companyId);
        return Ok(company);
    }

    [HttpPost]
    public async Task<ActionResult<Company>> CreateCompany([FromBody] Company company)
    {
        _companyRepository.AddCompany(company);
        await _companyRepository.SaveAsync();
        return CreatedAtRoute(nameof(GetCompany), new {companyId = company.Id}, company);
    }
}

至此就完成了一个简单的实体连接。之后的操作完全可以通过实体进行操作。后续还可以通过AutoMapper等工具对实体类进行映射等,这些更高级的操作,不在文本的讨论范围。

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注