首页 > 数据库 >asp.net restful ef core sqlite 自定义包的位置

asp.net restful ef core sqlite 自定义包的位置

时间:2023-09-03 17:57:02浏览次数:43  
标签:core sqlite set Name 自定义 get villaDTO VillaAPI public

MagicVilla_VillaAPI/MagicVilla_VillaAPI.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <RestorePackagesPath>..\packages</RestorePackagesPath>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="7.0.0-preview.5.22303.8" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.0-preview.5.22303.8" />
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0-preview.5.22303.8" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.10" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.10">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.10" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0-preview.5.22302.2" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.10">
      <PrivateAssets>all</PrivateAssets>
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    </PackageReference>
    <PackageReference Include="SQLite.CodeFirst" Version="1.7.0.34" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
  </ItemGroup>

</Project>

MagicVilla_VillaAPI/appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultSQLConnection": "Data Source=MagicVilla.db"
  }
}

MagicVilla_VillaAPI/appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

MagicVilla_VillaAPI/Program.cs


using MagicVilla_VillaAPI.Data;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);


// Add services to the container.
builder.Services.AddDbContext<ApplicationDbContext>(option =>
{
    // sqlite数据库的使用步骤
    // 0. 安装ef core中关于sqlite的依赖包  dotnet add package Microsoft.EntityFrameworkCore.Sqlite
    // 1. 需要删掉Migrations文件夹下所有的迁移文件 
    // 2. 然后重新生成迁移文件  dotnet ef migrations add <自定义的名称>
    //      出现错误: Method 'Fragment' in type 'Microsoft.EntityFrameworkCore.Design.Internal.CSharpHelper' from assembly 'Microsoft.EntityFrameworkCore.Design, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' does not have an implementation.
    //      这个错误的原因是你的 `Microsoft.EntityFrameworkCore.Design` 包的版本和你的 `Microsoft.EntityFrameworkCore` 包的版本不一致,导致了类型加载异常¹。你需要将这两个包的版本统一,最好都升级到最新的版本²。你可以使用以下命令来更新这两个包:
    //      也可能是没有安装
    //      ```bash
    //      dotnet add package Microsoft.EntityFrameworkCore --version 7.0.10
    //      dotnet add package Microsoft.EntityFrameworkCore.Design --version 7.0.10
    //      ```
    // 3. 进而重新创建数据表    dotnet ef database update
    option.UseSqlite(builder.Configuration.GetConnectionString("DefaultSQLConnection"));
});


builder.Services.AddControllers(option =>
{
    //option.ReturnHttpNotAcceptable=true;
}).AddNewtonsoftJson();

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

MagicVilla_VillaAPI/Models/Villa.cs

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using SQLite.CodeFirst;

namespace MagicVilla_VillaAPI.Models
{
    public class Villa
    {
        // 主键,即使不加上[Key],默认也是主键
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        public string Name { get; set; }
        public string Details { get; set; }
        public double Rate { get; set; }
        public int Sqft { get; set; }
        public int Occupancy { get; set; }
        public string ImageUrl { get; set; }
        public string Amenity { get; set; }

        public DateTime CreatedDate { get; set; }

        public DateTime UpdatedDate { get; set; }


    }
}

MagicVilla_VillaAPI/Models/Dto/VillaDTO.cs

using System.ComponentModel.DataAnnotations;

namespace MagicVilla_VillaAPI.Models.Dto
{
    public class VillaDTO
    {
        public int Id { get; set; }
        [Required]
        [MaxLength(30)]
        public string Name { get; set; }
        public string Details { get; set; }
        [Required]
        public double Rate { get; set; }
        public int Occupancy { get; set; }
        public int Sqft { get; set; }
        public string ImageUrl { get; set; }
        public string Amenity { get; set; }
    }
}

MagicVilla_VillaAPI/Models/Dto/VillaCreateDTO.cs

using System.ComponentModel.DataAnnotations;

namespace MagicVilla_VillaAPI.Models.Dto
{
    public class VillaCreateDTO
    {
        [Required]
        [MaxLength(30)]
        public string Name { get; set; }
        public string Details { get; set; }
        [Required]
        public double Rate { get; set; }
        public int Occupancy { get; set; }
        public int Sqft { get; set; }
        public string ImageUrl { get; set; }
        public string Amenity { get; set; }
    }
}

MagicVilla_VillaAPI/Models/Dto/VillaUpdateDTO.cs

using System.ComponentModel.DataAnnotations;

namespace MagicVilla_VillaAPI.Models.Dto
{
    public class VillaUpdateDTO
    {
        [Required]
        public int Id { get; set; }
        [Required]
        [MaxLength(30)]
        public string Name { get; set; }
        public string Details { get; set; }
        [Required]
        public double Rate { get; set; }
        [Required]
        public int Occupancy { get; set; }
        [Required]
        public int Sqft { get; set; }
        [Required]
        public string ImageUrl { get; set; }
        public string Amenity { get; set; }
    }
}

MagicVilla_VillaAPI/Controllers/VillaAPIController.cs

using MagicVilla_VillaAPI.Data;
using MagicVilla_VillaAPI.Models;
using MagicVilla_VillaAPI.Models.Dto;
using Microsoft.AspNetCore.JsonPatch;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace MagicVilla_VillaAPI.Controllers
{
    // 路由的名称回去控制类的前面的名称作为路径,保留VillaAPI,去掉Controller,也就是 api/VillaAPI
    //[Route("api/[controller]")]

    // 当然,也可以写死,写死的好处就是当我修改这个类的名称时候,不用考虑会影响路由路径
    [Route("api/VillaAPI")]
    [ApiController]
    public class VillaAPIController : ControllerBase
    {
        private readonly ApplicationDbContext _db;

        // 依赖注入数据库上下文
        public VillaAPIController(ApplicationDbContext db)
        {
            _db = db;
        }

        [HttpGet]
        [ProducesResponseType(StatusCodes.Status200OK)]
        public ActionResult<IEnumerable<VillaDTO>> GetVillas()
        {
            return Ok(_db.Villas.ToList());
        }

        [HttpGet("{id:int}", Name = "GetVilla")]
        [ProducesResponseType(StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        public ActionResult<VillaDTO> GetVilla(int id)
        {
            if (id == 0)
            {
                return BadRequest();
            }
            var villa = _db.Villas.FirstOrDefault(u => u.Id == id);
            if (villa == null)
            {
                return NotFound();
            }

            return Ok(villa);
        }

        [HttpPost]
        [ProducesResponseType(StatusCodes.Status201Created)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status500InternalServerError)]
        public ActionResult<VillaDTO> CreateVilla([FromBody] VillaCreateDTO villaDTO)
        {

            if (_db.Villas.FirstOrDefault(u => u.Name.ToLower() == villaDTO.Name.ToLower()) != null)
            {
                ModelState.AddModelError("CustomError", "Villa already Exists!");
                return BadRequest(ModelState);
            }

            if (villaDTO == null)
            {
                return BadRequest(villaDTO);
            }

            Villa model = new()
            {
                Amenity = villaDTO.Amenity,
                Details = villaDTO.Details,
                ImageUrl = villaDTO.ImageUrl,
                Name = villaDTO.Name,
                Occupancy = villaDTO.Occupancy,
                Rate = villaDTO.Rate,
                Sqft = villaDTO.Sqft,
                CreatedDate = DateTime.Now,
                UpdatedDate = DateTime.Now
            };

            _db.Villas.Add(model);
            _db.SaveChanges();

            // 会在response的head中增加一个location地址,指向新添加的地址
            // https://www.cnblogs.com/zhuoss/p/17674336.html
            return CreatedAtRoute("GetVilla", new { id = model.Id }, model);
            // return Ok(villaDTO);
        }

        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [HttpDelete("{id:int}", Name = "DeleteVilla")]
        public IActionResult DeleteVilla(int id)
        {
            if (id == 0)
            {
                return BadRequest();
            }
            var villa = _db.Villas.FirstOrDefault(u => u.Id == id);
            if (villa == null)
            {
                return NotFound();
            }
            _db.Villas.Remove(villa);
            _db.SaveChanges();
            return NoContent();

        }

        [HttpPut("{id:int}", Name = "UpdateVilla")]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public IActionResult UpdateVilla(int id, [FromBody] VillaUpdateDTO villaDTO)
        {
            if (villaDTO == null || id != villaDTO.Id)
            {
                return BadRequest();
            }

            // ef core很智能的是,你不需要先去根据id查找响应的数据,然后在修改,直接赋值,然后updade
            Villa model = new()
            {
                Amenity = villaDTO.Amenity,
                Details = villaDTO.Details,
                Id = villaDTO.Id,
                ImageUrl = villaDTO.ImageUrl,
                Name = villaDTO.Name,
                Occupancy = villaDTO.Occupancy,
                Rate = villaDTO.Rate,
                Sqft = villaDTO.Sqft,
                // 算了,本来想设置UpdatedDate这个属性自动更新的,但是sqlite好像有个时区问题,不好弄,手动更新了,额
                UpdatedDate = DateTime.Now
            };

            // 直接update  
            _db.Villas.Update(model);
            _db.SaveChanges();
            return NoContent();

        }


        // AsNoTracking(),很关键,ef core一次只能跟踪一个模型

        [HttpPatch("{id:int}", Name = "UpdatePartialVilla")]
        [ProducesResponseType(StatusCodes.Status204NoContent)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        public IActionResult UpdatePartialVilla(int id, JsonPatchDocument<VillaUpdateDTO> patchDTO)
        {
            if (patchDTO == null || id == 0)
            {
                return BadRequest();
            }

            // - `AsNoTracking` 是一个扩展方法(Extension Method),表示在查询时不跟踪(Track)实体的状态(State),也就是说,不将实体添加到上下文中的变化跟踪器(Change Tracker)中。这样做的原因是:
            //     - 提高性能:不跟踪实体可以减少内存消耗和查询时间,因为不需要为每个实体创建快照(Snapshot)和检查变化。
            //     - 避免冲突:不跟踪实体可以避免在更新或删除时出现冲突或异常,因为不会有多个实体引用同一个数据库行。下面会更新数据库
            var villa = _db.Villas.AsNoTracking().FirstOrDefault(u => u.Id == id);


            VillaUpdateDTO villaDTO = new()
            {
                Amenity = villa.Amenity,
                Details = villa.Details,
                Id = villa.Id,
                ImageUrl = villa.ImageUrl,
                Name = villa.Name,
                Occupancy = villa.Occupancy,
                Rate = villa.Rate,
                Sqft = villa.Sqft,
            };


            if (villa == null)
            {
                return BadRequest();
            }




            // - `patchDTO` 是一个 `JsonPatchDocument < VillaUpdateDTO >` 类型的参数,表示客户端发送的 JSON Patch 文档,这是一种表示部分更新内容的格式。
            // - `ApplyTo` 是一个扩展方法(Extension Method),表示将 JSON Patch 文档应用到一个对象上,并修改它的属性值。
            // - `villaDTO` 是一个 `VillaUpdateDTO` 类型的对象,表示一个数据传输对象(DTO),用来简化数据交换。这个对象包含了别墅实体的部分属性,比如 `Id`、`Name`、`Details` 等。
            // - `ModelState` 是一个 `ModelStateDictionary` 类型的属性,表示当前请求的模型状态(Model State),用来验证数据是否有效。
            // 将客户端发送的 JSON Patch 文档应用到别墅的数据传输对象上,并修改它的属性值,并传入模型状态参数来验证数据是否有效。
            patchDTO.ApplyTo(villaDTO, ModelState);

            Villa model = new()
            {
                Amenity = villaDTO.Amenity,
                Details = villaDTO.Details,
                Id = villaDTO.Id,
                ImageUrl = villaDTO.ImageUrl,
                Name = villaDTO.Name,
                Occupancy = villaDTO.Occupancy,
                Rate = villaDTO.Rate,
                Sqft = villaDTO.Sqft,
                UpdatedDate = DateTime.Now
            };

            _db.Villas.Update(model);
            _db.SaveChanges();

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            return NoContent();
        }

    }
}

MagicVilla_VillaAPI/Data/ApplicationDbContext.cs

using MagicVilla_VillaAPI.Models;
using Microsoft.EntityFrameworkCore;

namespace MagicVilla_VillaAPI.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        /// <summary>
        /// - `public` 是一个访问修饰符(Access Modifier),表示这个属性(Property)可以被任何类或对象访问。
        /// - `DbSet<Villa>` 是一个泛型类(Generic Class),表示一个数据库中的一张表,其中的泛型参数 `Villa` 表示表中的每一行对应一个 `Villa` 类型的对象。
        /// - `Villas` 是一个属性的名称,表示这个数据库表的名称,也可以用来查询或操作这个表中的数据。
        /// - `{ get; set; }` 是一个属性的访问器(Accessor),表示这个属性可以被获取或设置,也就是说,可以读取或修改这个表中的数据。
        /// </summary>
        public DbSet<Villa> Villas { get; set; }

        /// <summary>
        /// 重写这个方法,可以在创建表的时候,同时初始化一些数据 
        /// </summary>
        /// <param name="modelBuilder"></param>
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {

            // getdate()是sqlserver支持的函数,sqlite不支持
            // modelBuilder.Entity<Villa>()
            //     .Property(v => v.UpdatedDate)
            //     .HasDefaultValueSql("getdate()");

            // sqlite支持CURRENT_TIMESTAMP
            modelBuilder.Entity<Villa>()
                .Property(v => v.UpdatedDate)
                .HasDefaultValueSql("CURRENT_TIMESTAMP");


            modelBuilder.Entity<Villa>().HasData(
                    new Villa
                    {
                        Id = 1,
                        Name = "Royal Villa",
                        Details = "Fusce 11 tincidunt maximus leo, sed scelerisque massa auctor sit amet. Donec ex mauris, hendrerit quis nibh ac, efficitur fringilla enim.",
                        ImageUrl = "https://dotnetmasteryimages.blob.core.windows.net/bluevillaimages/villa3.jpg",
                        Occupancy = 4,
                        Rate = 200,
                        Sqft = 550,
                        Amenity = "",
                        CreatedDate = DateTime.Now
                    },
                  new Villa
                  {
                      Id = 2,
                      Name = "Premium Pool Villa",
                      Details = "Fusce 11 tincidunt maximus leo, sed scelerisque massa auctor sit amet. Donec ex mauris, hendrerit quis nibh ac, efficitur fringilla enim.",
                      ImageUrl = "https://dotnetmasteryimages.blob.core.windows.net/bluevillaimages/villa1.jpg",
                      Occupancy = 4,
                      Rate = 300,
                      Sqft = 550,
                      Amenity = "",
                      CreatedDate = DateTime.Now
                  },
                  new Villa
                  {
                      Id = 3,
                      Name = "Luxury Pool Villa",
                      Details = "Fusce 11 tincidunt maximus leo, sed scelerisque massa auctor sit amet. Donec ex mauris, hendrerit quis nibh ac, efficitur fringilla enim.",
                      ImageUrl = "https://dotnetmasteryimages.blob.core.windows.net/bluevillaimages/villa4.jpg",
                      Occupancy = 4,
                      Rate = 400,
                      Sqft = 750,
                      Amenity = "",
                      CreatedDate = DateTime.Now
                  },
                  new Villa
                  {
                      Id = 4,
                      Name = "Diamond Villa",
                      Details = "Fusce 11 tincidunt maximus leo, sed scelerisque massa auctor sit amet. Donec ex mauris, hendrerit quis nibh ac, efficitur fringilla enim.",
                      ImageUrl = "https://dotnetmasteryimages.blob.core.windows.net/bluevillaimages/villa5.jpg",
                      Occupancy = 4,
                      Rate = 550,
                      Sqft = 900,
                      Amenity = "",
                      CreatedDate = DateTime.Now
                  },
                  new Villa
                  {
                      Id = 5,
                      Name = "Diamond Pool Villa",
                      Details = "Fusce 11 tincidunt maximus leo, sed scelerisque massa auctor sit amet. Donec ex mauris, hendrerit quis nibh ac, efficitur fringilla enim.",
                      ImageUrl = "https://dotnetmasteryimages.blob.core.windows.net/bluevillaimages/villa2.jpg",
                      Occupancy = 4,
                      Rate = 600,
                      Sqft = 1100,
                      Amenity = "",
                      CreatedDate = DateTime.Now
                  });
        }
    }
}

标签:core,sqlite,set,Name,自定义,get,villaDTO,VillaAPI,public
From: https://www.cnblogs.com/zhuoss/p/17675269.html

相关文章

  • vue自定义事件用法及$emit
    子组件<template><button@click="handle">自定义事件</button></template><script>exportdefault{data(){return{message:"我子组件"}},methods:{handle(){......
  • EF Core 的基本使用
    基本命令EFCore的迁移(Migration)是一种用于管理数据库架构变化的功能,它可以根据你的数据模型自动生成和执行数据库创建或者更新的SQL语句。EFCore提供了一些命令行工具,让你可以方便地操作迁移。以下是一些常用的迁移命令:dotnetefmigrationsadd<name>:这个命令用于创建一......
  • sqlite 触发器 c#
    sqlite触发器我看到你在使用EntityFrameworkCore和SQLite数据库,想让别墅实体的UpdatedDate属性在更新时自动生成。这是一个使用CodeFirst的问题,关于如何配置实体属性的值生成策略(ValueGenerationStrategy)。要实现这个功能,你需要遵循以下步骤:属性注释使用[Databa......
  • 自定义CUDA实现PyTorch算子的四种简单方法
    背景在探索新的深度学习算法的时候,我们可能会遇到PyTorch提供的算子不能满足需求的情况,这时候就需要自定义PyTorch算子,将我们的算法集成到PyTorch的工作流中。同时,为了提高运算效率,算子往往都需要使用CUDA实现。所幸,PyTorch及很多其他Python库都提供了简化这一过程的方法,完全不需......
  • python操作sqlite
    importjsonimportsqlite3importpandasaspdclassSqliteTool:def__init__(self,db_path):self.db_path=db_pathself.conn=sqlite3.connect(self.db_path)self.conn.row_factory=sqlite3.Rowself.cursor=self.con......
  • C++ Core Guidelines解析 电子书 pdf
    关注公众号:红宸笑。回复:电子书即可  在《C++CoreGuidelines解析》中,C++专家讲师RainerGrimm提炼出了CoreGuidelines中的精髓,去除了晦涩难懂的内容,分享了新的见解和背景,并提供了自己培训课程中经过充分测试的示例。对于使用C++11及后续版本C++的有经验程序员,G......
  • C#/.NET/.NET Core优秀项目和框架8月简报
    思维导航前言FreeIMDotNetCore.SKIT.FlurlHttpClient.WechatVPetSSCMSBlog.CoreGeekDeskAgileConfigKopSoftWms加入DotNetGuide技术交流群前言公众号每月定期推广和分享的C#/.NET/.NETCore优秀项目和框架(公众号每周至少推荐两个优秀的项目和框架当然节假日除外......
  • .NET Core如何使用第三方组件Autofac
     首先先了解一下什么是AutofacAutofac用于在.NETCore应用程序中管理组件的生命周期和依赖关系。我们在开发一个项目的时在Program中注入依赖注入的生命周期,项目工程比较大的时候我们就要实现很多注入,最致命的缺点就是耽误太多时间,为解决这一问题的最好解决方法就是使用到......
  • dotnet SemanticKernel 入门 自定义变量和技能
    本文将告诉大家如何在SemanticKernel框架内定义自定义的变量和如何开发自定义的技能本文属于SemanticKernel入门系列博客,更多博客内容请参阅我的博客导航自定义变量是一个非常有用的技能,自定义变量可以让炼丹师和程序员进行并行工作。由炼丹师对AI模型进行训练,从而找到对......
  • uniapp项目实践总结(六)自定义顶部导航栏
    本篇主要讲述如何自定义顶部导航栏,有时候默认导航栏不足以满足我们的需求,这时候就需要自定义导航栏来解决这个问题。目录默认导航修改配置自定义顶部默认导航自带的默认顶部导航设置的内容有限,不容易扩展修改,因此如果有更加个性化的需求,则需要自定义顶部导航。配置如下......