日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Asp.net Core基于MVC框架实现PostgreSQL操作

發布時間:2023/12/4 数据库 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Asp.net Core基于MVC框架实现PostgreSQL操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

簡單介紹

Asp.net Core最大的價值在于跨平臺、跨平臺、跨平臺。重要的事情說三遍。但是目前畢竟是在開發初期,雖然推出了1.0.0 正式版,但是其實好多功能還沒有完善。比方說編譯時的一些文件編碼問題,輔助工具Tools的一些Bug,還有一些好用的模板和平臺實現尚未完成等一些問題。但這畢竟是一個好的開始,并且在Github上,大家都還在積極的完善,你也可以參與進來。地址:https://github.com/aspnet

Asp.net Core在學習的時候,首先你應該跟著微軟官方的入門教材來學習,在這里:?https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html。這個入門教材很淺顯易懂的讓你了解了Asp.net Core mvc框架以及entity framework core的用法。不過缺點是,使用的是Sql compact數據庫,也就是SQL Server數據庫。要知道,我們使用Asp.net 的主要目的是實現跨平臺部署,所以數據庫的選擇上,首選肯定不是SqlServer,否則意義何在?當然,目前Entity Framework core暫時還不支持所有數據庫。截止2016年7月,支持情況如下:

Database Providers

The following providers are available

  • Microsoft SQL Server

  • SQLite

  • Npgsql (PostgreSQL)

  • Microsoft SQL Server Compact Edition

  • IBM Data Servers

  • InMemory (for Testing)

  • Devart (MySQL, Oracle, PostgreSQL, SQLite, DB2, SQL Server, and more)

  • MySQL (Coming Soon)

  • Oracle (Coming Soon)

所以提供給我們選擇的數據庫還是有限的(主要是不支持MySql,Devart這東西筆者不了解,不評論)。總得來說,對MS SQL Server的支持肯定是最好的,所以場景允許下,首選Sql server。其次,就DB2和PostgreSQL可選了。筆者不喜歡DB2(很多原因,主要是開發操作管理麻煩,并非說DB2本身存在問題),PostgreSQL其實也不太好用,不過誰叫他免費呢,肯定是好多國內公司首選。

PostgreSQL本身歷史悠久,記得好像上世紀80年代就存在了,免費開源,而且是有專門社區維護。設計理念是以健壯性為首選,所以收到光打企業級平臺歡迎。關于PostgreSQL和MySQL之間的優缺點,這個其實不太好說,MySQL在損失健壯性的同時,提高了性能,并且支持很多非標準新特性,而PostgreSQL在健壯性上,號稱不弱于Oracle,性能優秀,完全支持SQL標準,所以其實并不差。

準備環境

Ubuntu Server(16.04)虛擬機1臺,IP:192.168.1.6 預裝了PostgreSQL數據庫,并配置好防火墻,ssh連接等基礎環境。確保能夠外部訪問。

VS2015 Update3

Putty 和SSH Secure File Transfer Client

服務器環境部署

????參考之前的博客:http://blog.csdn.net/lanwilliam/article/details/51880124

開始

  • 新建項目,選擇Asp.net Core Web Application項目模板。

  • 選擇Web應用程序模板,然后修改身份驗證哪里,選擇不進行身份驗證。

    這里要說一下,Asp.net core項目中,包含一個Identity子項目,在GitHub上有介紹如下:

    這里大家一看就知道了,這就是原來提供的ASP.net自帶的權限框架。這個框架現在其實非常強大了,還支持Google和TWriter等OAuth用法,不過缺點是只支持SQL Server數據庫。如果選擇了個人用戶賬戶,那么會默認使用這個框架創建項目。我們希望用PostgreSQL,所以不能選他,很遺憾。而且目前創建控制器等一些內置模板用法,都是基于SqlServer,用到這個Identity,大家如果看過微軟的GettingStarted,就會看到介紹,所以建議大家首先學習微軟GettingStarted。

    當然,不要勾選云中托管。

  • 空白項目結構

    上圖是新建完成的空白項目結構,你會發現Models,Data等文件夾都不存在,這里需要手動新建,并且丟進去一個class。

    必須要丟進去個class文件,讓類定義的時候聲明出Models和Data的命名空間,否則待會生成models文件的時候會報錯。

  • 增加項目引用

    Asp.net core項目有兩種方法增加引用,一種是直接修改project.json,另一種是nuget。

    上述方法打開控制臺

    輸入如下命令

    會發現最后的Tools安裝不了,可能nuget沒同步過來,可以在project.json中手動添加。

    最后的文件如下:

    主要是圈選中的部分。可以看到這里我們用來操作PostgreSQL的Provider是Npgsql,這是aspnet下的一個子項目。可以在github找到。

    其他EntityFrameworkCore的引用,是從示例項目中搬來的。

  • 生成Models文件

    這里要說明一下,微軟MVC教程中時使用的模板創建的Controller,他會自動創建ApplicationDBContext和對應的Views視圖文件,以及一些其他的內容。因為他更新了ApplicationDBContext文件和ApplicationDbContextModelSnapshot文件,所以控制臺執行dotnet ef命令才會正常完成,這里無法用到這些方法。因為沒選"個人用戶賬戶",這里請自行嘗試。

    dotnet ef migrations add Initial

    dotnet ef database update

    由于自行寫DBContext類實現太麻煩,我們這里采取開發中常用的辦法,首先設計數據庫,然后根據數據庫生成類。

    在數據庫新建表如下:(測試用,看看就好)

    然后回到VS2015,在Nuget程序包控制臺輸入:

    Scaffold-DbContext "Server=192.168.1.6;Database=testdb;User ID=test;Password=test;" Npgsql.EntityFrameworkCore.PostgreSQL -OutputDir Models

  • 這個命令不用解釋了吧?數據庫連接,使用的數據庫provider和輸出目錄。

    順利完成的話,Models下會出現幾個類文件。

    如果報錯的話,請根據錯誤提示進行處理。處理原則,首先保證程序能夠編譯通過,然后確保Models下面沒有存在本次要生成的同名文件,然后確認目前系統沒有其他DBContext存在。現在dotnet core的好多工具都在完善中,健壯性都有待提高。

    打開看看生成的文件:

    ?

    using?System;

    using?Microsoft.EntityFrameworkCore;

    using?Microsoft.EntityFrameworkCore.Metadata;

    ?

    namespace?PostgresSqlDemo.Models

    {

    public?partial?class?testdbContext?:?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=192.168.1.6;Database=testdb;User ID=test;Password=test;");

    }

    ?

    protected?override?void?OnModelCreating(ModelBuilder?modelBuilder)

    {

    modelBuilder.Entity<Blog>(entity =>

    {

    entity.ToTable("blog");

    ?

    entity.Property(e => e.Id)

    .HasColumnName("id")

    .ValueGeneratedNever();

    ?

    entity.Property(e => e.Title)

    .IsRequired()

    .HasColumnName("title")

    .HasColumnType("varchar")

    .HasMaxLength(300);

    ?

    entity.Property(e => e.Url)

    .IsRequired()

    .HasColumnName("url")

    .HasColumnType("varchar")

    .HasMaxLength(300);

    });

    ?

    modelBuilder.Entity<TbUser>(entity =>

    {

    entity.HasKey(e => e.Userid)

    .HasName("PK_tb_user");

    ?

    entity.ToTable("tb_user");

    ?

    entity.Property(e => e.Userid)

    .HasColumnName("userid")

    .ValueGeneratedNever();

    ?

    entity.Property(e => e.Age).HasColumnName("age");

    ?

    entity.Property(e => e.Name)

    .IsRequired()

    .HasColumnName("name")

    .HasColumnType("varchar")

    .HasMaxLength(30);

    });

    }

    ?

    public?virtual?DbSet<Blog> Blog {?get;?set; }

    public?virtual?DbSet<TbUser> TbUser {?get;?set; }

    }

    }

    Entityframework中,默認是一個數據庫使用唯一一個DBContext類進行管理。

  • 修改DBContext文件

    模板已經提示給你,需要修改這部分代碼,實現動態配置連接的目的。

    進行如下修改:

    注釋掉OnConfiguring方法,增加構造函數,我們把注冊放到Startup中去完成。

  • 添加數據庫連接配置項

    打開appsetting.json文件,增加如下配置:

    其實這就相當于原來asp.net中的Web.config中的ConnectionStrings。

  • 注冊DBContext

    打開StartUP.cs 文件,找到ConfigureServices方法,添加選中代碼:

  • ????????到這里就看明白了吧,注冊DBContext,使用Npgsql,并給出數據庫連接字符串。

  • 增加控制器Controller

    在Controller文件夾下新建Controller文件,并添加如下代碼:

    using?Microsoft.AspNetCore.Mvc;

    using?PostgresSqlDemo.Data;

    using?PostgresSqlDemo.Models;

    using?System;

    using?System.Collections.Generic;

    using?System.Linq;

    using?System.Threading.Tasks;

    using?Microsoft.EntityFrameworkCore;

    ?

    namespace?PostgresSqlDemo.Controllers

    {

    public?class?TbUserController?:?Controller

    {

    private?readonly?testdbContext?_context;

    ?

    public?TbUserController(testdbContext?context)

    {

    _context = context;

    }

    ?

    // GET: tbusers

    public?async?Task<IActionResult> Index()

    {

    return?View(await?_context.TbUser.ToListAsync());

    }

    ?

    public?async?Task<IActionResult> Details(Guid? id)

    {

    if?(id ==?null)

    {

    return?NotFound();

    }

    ?

    var?tbuser =?await?_context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    if?(tbuser ==?null)

    {

    return?NotFound();

    }

    ?

    return?View(tbuser);

    }

    ?

    // GET: tbusers/Create

    public?IActionResult?Create()

    {

    return?View();

    }

    ?

    // POST: tbusers/Create

    // To protect from overposting attacks, please enable the specific properties you want to bind to, for

    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

    [HttpPost]

    [ValidateAntiForgeryToken]

    public?async?Task<IActionResult> Create([Bind("Userid,Name,Age")]?TbUser?tbuser)

    {

    if?(ModelState.IsValid)

    {

    tbuser.Userid =?Guid.NewGuid();

    _context.Add(tbuser);

    await?_context.SaveChangesAsync();

    return?RedirectToAction("Index");

    }

    return?View(tbuser);

    }

    ?

    // GET: tbusers/Edit/5

    public?async?Task<IActionResult> Edit(Guid? id)

    {

    if?(id ==?null)

    {

    return?NotFound();

    }

    ?

    var?tbuser =?await?_context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    if?(tbuser ==?null)

    {

    return?NotFound();

    }

    return?View(tbuser);

    }

    ?

    // POST: tbusers/Edit/5

    // To protect from overposting attacks, please enable the specific properties you want to bind to, for

    // more details see http://go.microsoft.com/fwlink/?LinkId=317598.

    [HttpPost]

    [ValidateAntiForgeryToken]

    public?async?Task<IActionResult> Edit(Guid?id, [Bind("Userid,Name,Age")]?TbUser?tbuser)

    {

    if?(id != tbuser.Userid)

    {

    return?NotFound();

    }

    ?

    if?(ModelState.IsValid)

    {

    try

    {

    _context.Update(tbuser);

    await?_context.SaveChangesAsync();

    }

    catch?(DbUpdateConcurrencyException)

    {

    if?(!tbuserExists(tbuser.Userid))

    {

    return?NotFound();

    }

    else

    {

    throw;

    }

    }

    return?RedirectToAction("Index");

    }

    return?View(tbuser);

    }

    ?

    // GET: tbusers/Delete/5

    public?async?Task<IActionResult> Delete(Guid? id)

    {

    if?(id ==?null)

    {

    return?NotFound();

    }

    ?

    var?tbuser =?await?_context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    if?(tbuser ==?null)

    {

    return?NotFound();

    }

    ?

    return?View(tbuser);

    }

    ?

    // POST: tbusers/Delete/5

    [HttpPost,?ActionName("Delete")]

    [ValidateAntiForgeryToken]

    public?async?Task<IActionResult> DeleteConfirmed(Guid?id)

    {

    var?tbuser =?await?_context.TbUser.SingleOrDefaultAsync(m => m.Userid == id);

    _context.TbUser.Remove(tbuser);

    await?_context.SaveChangesAsync();

    return?RedirectToAction("Index");

    }

    ?

    private?bool?tbuserExists(Guid?id)

    {

    return?_context.TbUser.Any(e => e.Userid == id);

    }

    }

    }

    如果你看過Getting Started Asp.net core MVC的話,相信應該能夠看懂,基本是把使用新增Controller模板生成的方法修改了一下拿過來用了。

    Asp.net core mvc中,默認路由名成為(name)Controller,所以我們這里叫TbUserController,訪問的時候是http://youip/TbUser這樣。并且默認是觸發Index方法。

    Controller中,每個方法,都相當于一個客戶端Form的Action。沒有特殊聲明的方法,默認為HttpGet,可以直接請求。需要Post數據的,請手動增加[HttpPost]聲明。

    Async是C# 5.0后提供的關鍵字,是自動實現一個異步的方法,需要配合await關鍵字使用。Await會被自動轉換為一個async的異步請求,后面的代碼,會被自動放到completed方法中執行。這樣處理能夠極大的提高服務器的并發性能,具體請自行學習。

  • 增加Views頁面

    增加對應的頁面如下:

  • Index.cshtml

    @model?IEnumerable<PostgresSqlDemo.Models.TbUser>

    ?

    @{

    ViewData["Title"] =?"Index";

    }

    ?

    <h2>Index</h2>

    ?

    <p>

    <a?asp-action="Create">Create New</a>

    </p>

    <table?class="table">

    <thead>

    <tr>

    <th>

    @Html.DisplayNameFor(model => model.Userid)

    </th>

    <th>

    @Html.DisplayNameFor(model => model.Name)

    </th>

    <th>

    @Html.DisplayNameFor(model => model.Age)

    </th>

    ?

    <th></th>

    </tr>

    </thead>

    <tbody>

    @foreach?(var?item?in?Model)

    {

    <tr>

    <td>

    @Html.DisplayFor(modelItem => item.Userid)

    </td>

    <td>

    @Html.DisplayFor(modelItem => item.Name)

    </td>

    <td>

    @Html.DisplayFor(modelItem => item.Age)

    </td>

    ?

    <td>

    <a?asp-action="Edit"?asp-route-id="@item.Userid">Edit</a>?|

    <a?asp-action="Details"?asp-route-id="@item.Userid">Details</a>?|

    <a?asp-action="Delete"?asp-route-id="@item.Userid">Delete</a>

    </td>

    </tr>

    }

    </tbody>

    </table>

    ?

    Create.cshtml

    @model?PostgresSqlDemo.Models.TbUser

    ?

    @{

    ViewData["Title"] =?"Create";

    }

    ?

    <h2>Create</h2>

    ?

    <form?asp-action="Create">

    <div?class="form-horizontal">

    <h4>TbUser</h4>

    <hr?/>

    <div?asp-validation-summary="ModelOnly"?class="text-danger"></div>

    <div?class="form-group">

    <label?asp-for="Name"?class="col-md-2 control-label"></label>

    <div?class="col-md-10">

    <input?asp-for="Name"?class="form-control"?/>

    <span?asp-validation-for="Name"?class="text-danger"?/>

    </div>

    </div>

    <div?class="form-group">

    <label?asp-for="Age"?class="col-md-2 control-label"></label>

    <div?class="col-md-10">

    <input?asp-for="Age"?class="form-control"?/>

    <span?asp-validation-for="Age"?class="text-danger"?/>

    </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>

    ?

    <div>

    <a?asp-action="Index">Back to List</a>

    </div>

    ?

    @section Scripts {

    @{await?Html.RenderPartialAsync("_ValidationScriptsPartial");}

    }

    ?

    Delete.cshtml

    @model?PostgresSqlDemo.Models.TbUser

    ?

    @{

    ViewData["Title"] =?"Delete";

    }

    ?

    <h2>Delete</h2>

    ?

    <h3>Are you sure you want to delete this?</h3>

    <div>

    <h4>Blog</h4>

    <hr?/>

    <dl?class="dl-horizontal">

    <dt>

    @Html.DisplayNameFor(model => model.Userid)

    </dt>

    <dd>

    @Html.DisplayFor(model => model.Userid)

    </dd>

    <dt>

    @Html.DisplayNameFor(model => model.Name)

    </dt>

    <dd>

    @Html.DisplayFor(model => model.Name)

    </dd>

    <dt>

    @Html.DisplayNameFor(model => model.Age)

    </dt>

    <dd>

    @Html.DisplayFor(model => model.Age)

    </dd>

    </dl>

    ?

    <form?asp-action="Delete">

    <div?class="form-actions no-color">

    <input?type="submit"?value="Delete"?class="btn btn-default"?/>?|

    <a?asp-action="Index">Back to List</a>

    </div>

    </form>

    </div>

    ?

    Details.cshtml

    @model?PostgresSqlDemo.Models.TbUser

    ?

    @{

    ViewData["Title"] =?"Details";

    }

    ?

    <h2>Details</h2>

    ?

    <div>

    <h4>Blog</h4>

    <hr?/>

    <dl?class="dl-horizontal">

    <dt>

    @Html.DisplayNameFor(model => model.Userid)

    </dt>

    <dd>

    @Html.DisplayFor(model => model.Userid)

    </dd>

    <dt>

    @Html.DisplayNameFor(model => model.Name)

    </dt>

    <dd>

    @Html.DisplayFor(model => model.Name)

    </dd>

    <dt>

    @Html.DisplayNameFor(model => model.Age)

    </dt>

    <dd>

    @Html.DisplayFor(model => model.Age)

    </dd>

    </dl>

    </div>

    <div>

    <a?asp-action="Edit"?asp-route-id="@Model.Userid">Edit</a>?|

    <a?asp-action="Index">Back to List</a>

    </div>

    ?

    Edit.cshtml

    @model?PostgresSqlDemo.Models.TbUser

    ?

    @{

    ViewData["Title"] =?"Edit";

    }

    ?

    <h2>Edit</h2>

    ?

    <form?asp-action="Edit">

    <div?class="form-horizontal">

    <h4>Blog</h4>

    <hr?/>

    <div?asp-validation-summary="ModelOnly"?class="text-danger"></div>

    <input?type="hidden"?asp-for="Userid"?/>

    <div?class="form-group">

    <label?asp-for="Name"?class="col-md-2 control-label"></label>

    <div?class="col-md-10">

    <input?asp-for="Name"?class="form-control"?/>

    <span?asp-validation-for="Name"?class="text-danger"?/>

    </div>

    </div>

    <div?class="form-group">

    <label?asp-for="Age"?class="col-md-2 control-label"></label>

    <div?class="col-md-10">

    <input?asp-for="Age"?class="form-control"?/>

    <span?asp-validation-for="Age"?class="text-danger"?/>

    </div>

    </div>

    <div?class="form-group">

    <div?class="col-md-offset-2 col-md-10">

    <input?type="submit"?value="Save"?class="btn btn-default"?/>

    </div>

    </div>

    </div>

    </form>

    ?

    <div>

    <a?asp-action="Index">Back to List</a>

    </div>

    ?

    @section Scripts {

    @{await?Html.RenderPartialAsync("_ValidationScriptsPartial");}

    }

    ?

  • 增加驗證腳本引用View文件

    <environment?names="Development">

    <script?src="~/lib/jquery-validation/dist/jquery.validate.js"></script>

    <script?src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>

    </environment>

    <environment?names="Staging,Production">

    <script?src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"

    asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"

    asp-fallback-test="window.jQuery && window.jQuery.validator">

    </script>

    <script?src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"

    asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"

    asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive">

    </script>

    </environment>

  • ?

  • 修改Layout.cshtml文件

    增加如上兩個連接。Blog的添加參考TbUser。這里主要是想讓大家看出來DBContext的用法,所以特意弄了兩個實體類。

  • 然后vs里面可以運行了,效果如下:

    這里沒有改默認的頁面。

    再看我們加的頁面。

    并且asp.net mvc默認使用了bootstrap,所以我們可以用chrome的手機模式看看。

    ??

  • 改成中文顯示

    改一下TbUser.cs

    using?System;

    using?System.Collections.Generic;

    using?System.ComponentModel.DataAnnotations;

    ?

    namespace?PostgresSqlDemo.Models

    {

    public?partial?class?TbUser

    {

    [Display(Name =?"用戶編號")]

    public?Guid?Userid {?get;?set; }

    [Display(Name =?"用戶姓名")]

    public?string?Name {?get;?set; }

    [Display(Name =?"用戶年齡")]

    public?int? Age {?get;?set; }

    }

    }

    再看看頁面

    ?

  • 加一下驗證

  • ????改成中文驗證

    ????????????[Display(Name =?"用戶姓名")]

    ????????[StringLength(10, MinimumLength = 3,ErrorMessage =?"字段{0}長度不能小于3,總長度不能大于10")]

    ????????[Required]

    ????public?string?Name {?get;?set; }

    ????

  • 最后就是部署到Ubuntu服務器了。

    將WebApp項目發布出來,使用SSH Secure File Transfer上傳到服務器,然后參照前文發布。

    前文:http://blog.csdn.net/lanwilliam/article/details/51880124

  • 總結:

    ????Asp.net Core 目前來說功能性還不完善,暫時不建議大型應用往上遷移,但是如果是小型項目,比較簡單,可以在仔細論證后嘗試使用。注意仔細論證,因為目前.net core并不是所有類庫都能夠實現跨平臺。簡單來說,System.Drawing就無法使用,所以后臺畫水印就需要其他三方庫,這個請自行仔細論證。不過小項目發布到linux虛擬機上面,確實可以省一筆錢。

    原文地址:http://www.cnblogs.com/lanwilliam/p/5663931.html


    .NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

    總結

    以上是生活随笔為你收集整理的Asp.net Core基于MVC框架实现PostgreSQL操作的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。