同系列文章:
参考文章
ASP.NET Core Application to Existing Database (Database First)
前提条件
- Visual Studio 2015 Update 3
- .NET Core for Visual Studio
- postgres database
创建新工程
- 工程模板:Visual C#->Web->ASP.NET Core Web Application (.NET Core)
- 项目名称:EFGetStarted.AspNetCore.ExistingDb
- 模板:Web应用程序
- 身份验证:不进行身份验证
通过NuGet安装Entity Framework并更新文件project.json中“tools”区
- Install-Package Npgsql.EntityFrameworkCore.PostgreSQL
- Install-Package Npgsql.EntityFrameworkCore.PostgreSQL.Design
- Install-Package Microsoft.EntityFrameworkCore.Tools -Pre
"tools": { "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final", "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" },
数据模型反向工程
工具 -> NuGet包管理器 -> 程序包管理器控制台运行如下命令
Scaffold-DbContext "Server=localhost;Database=postgres;User ID=postgres;Password=wantgirl;" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Models
将在Models目录下自动生成Blogs.cs、Posts.cs、postgresContext.cs三个文件。
Blogs.cs
using System; using System.Collections.Generic; namespace EFGetStarted.AspNetCore.ExistingDb.Models { public partial class Blogs { public Blogs() { Posts = new HashSet<Posts>(); } public int BlogId { get; set; } public string Url { get; set; } public virtual ICollection<Posts> Posts { get; set; } } }
Posts.cs
using System; using System.Collections.Generic; namespace EFGetStarted.AspNetCore.ExistingDb.Models { public partial class Posts { public int PostId { get; set; } public int BlogId { get; set; } public string Content { get; set; } public string Title { get; set; } public virtual Blogs Blog { get; set; } } }
postgresContext.cs
using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; namespace EFGetStarted.AspNetCore.ExistingDb.Models { public partial class postgresContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. optionsBuilder.UseNpgsql(@"Server=localhost;Database=postgres;User ID=postgres;Password=wantgirl;"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blogs>(entity => { entity.HasKey(e => e.BlogId) .HasName("PK_Blogs"); }); modelBuilder.Entity<Posts>(entity => { entity.HasKey(e => e.PostId) .HasName("PK_Posts"); entity.HasIndex(e => e.BlogId) .HasName("IX_Posts_BlogId"); entity.HasOne(d => d.Blog) .WithMany(p => p.Posts) .HasForeignKey(d => d.BlogId); }); } public virtual DbSet<Blogs> Blogs { get; set; } public virtual DbSet<Posts> Posts { get; set; } } }
通过依赖注入注册上下文
更新Models\postgresContext.cs,删除OnConfiguring成员方法,并添加postgresContext构造函数。
postgresContext.cs
using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; namespace EFGetStarted.AspNetCore.ExistingDb.Models { public partial class postgresContext : DbContext { public postgresContext(DbContextOptions<postgresContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blogs>(entity => { entity.HasKey(e => e.BlogId) .HasName("PK_Blogs"); }); modelBuilder.Entity<Posts>(entity => { entity.HasKey(e => e.PostId) .HasName("PK_Posts"); entity.HasIndex(e => e.BlogId) .HasName("IX_Posts_BlogId"); entity.HasOne(d => d.Blog) .WithMany(p => p.Posts) .HasForeignKey(d => d.BlogId); }); } public virtual DbSet<Blogs> Blogs { get; set; } public virtual DbSet<Posts> Posts { get; set; } } }
在Startup.cs中引入命名空间
using EFGetStarted.AspNetCore.ExistingDb.Models; using Microsoft.EntityFrameworkCore;
更新Startup.cs中的ConfigureServices成员方法
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddApplicationInsightsTelemetry(Configuration); services.AddDbContext<postgresContext>(options => options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))); services.AddMvc(); }
连接字符串格式
User ID=root;Password=myPassword;Host=localhost;Port=5432;Database=myDataBase;Pooling=true;Min Pool Size=0;Max Pool Size=100;Connection Lifetime=0;
在Appsetting.json中增加连接字符串
"ConnectionStrings": { "DefaultConnection": "User ID=postgres;Password=wantgirl;Host=localhost;Database=postgres;Pooling=true;" },
创建MVC控制器
BlogsController.cs
using EFGetStarted.AspNetCore.ExistingDb.Models; using Microsoft.AspNetCore.Mvc; using System.Linq; namespace EFGetStarted.AspNetCore.ExistingDb.Controllers { public class BlogsController : Controller { private postgresContext _context; public BlogsController(postgresContext context) { _context = context; } public IActionResult Index() { return View(_context.Blogs.ToList()); } public IActionResult Create() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public IActionResult Create(Blogs blog) { if (ModelState.IsValid) { _context.Blogs.Add(blog); _context.SaveChanges(); return RedirectToAction("Index"); } return View(blog); } } }
创建视图
Index.cshtml
@model IEnumerable<EFGetStarted.AspNetCore.ExistingDb.Models.Blogs> @{ ViewBag.Title = "Blogs"; } <h2>Blogs</h2> <p> <a asp-controller="Blogs" asp-action="Create">Create New</a> </p> <table class="table"> <tr> <th>Id</th> <th>Url</th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.BlogId) </td> <td> @Html.DisplayFor(modelItem => item.Url) </td> </tr> } </table>
Create.cshtml
@model EFGetStarted.AspNetCore.ExistingDb.Models.Blogs @{ ViewBag.Title = "New Blog"; } <h2>@ViewData["Title"]</h2> <form asp-controller="Blogs" asp-action="Create" method="post" class="form-horizontal" role="form"> <div class="form-horizontal"> <div asp-validation-summary="All" class="text-danger"></div> <div class="form-group"> <label asp-for="Url" class="col-md-2 control-label"></label> <div class="col-md-10"> <input asp-for="Url" class="form-control" /> <span asp-validation-for="Url" class="text-danger"></span> </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> </form>