ASP使用EFCore和AutoMapper添加导航属性数据

目录

一、不使用自增主键

(1)下载AutoMapper的nuget包

(2)配置映射规则

(3)配置MappingProfile文件

(4)控制器编写添加控制器

(5)测试

二、使用自增主键

(1)数据库设置自增

(2)实体和Dto类

(3)控制器


实体类:

cs 复制代码
 [Table("BLOG")]
 public class Blog
 {
     [Column("BLOGID")]
     //手动生成,不需要数据库自动生成
     [DatabaseGenerated(DatabaseGeneratedOption.None)]
     [Key]
     public int BlodId { get; set; }
     [Column("URL")]
     public string Url { get; set; }

     public ICollection<Post> Posts { get; set; }
 }
cs 复制代码
[Table("POST")]
public class Post
{
    [Column("POSTID")]
    //手动生成,不需要数据库自动生成
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    [Key]
    public int PostId { get; set; }
    [Column("TITLE")]
    public string Title { get; set; }
    [Column("CONTENT")]
    public string Content { get; set; }
    [Column("BLOGID")]
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

Dto类:

cs 复制代码
public class BlogDto
{
    public int BlodId { get; set; }
    public string Url { get; set; }

    public ICollection<PostDto> Posts { get; set; }
}
cs 复制代码
 public class PostDto
 {
     public int PostId { get; set; }
     public string Title { get; set; }
     public string Content { get; set; }
     public int BlogId { get; set; }
 }

一、不使用自增主键

该项目数据库和实体都没有设置自增属性。

(1)下载AutoMapper的nuget包

(2)配置映射规则

在如下的MappingProfile文件中配置映射规则,也就是实体类和Dto之间的转换

为什么要配置正向和反向的映射?

  • 从 DTO 到实体: 当客户端向服务器发送数据时,通常会发送 DTO 对象。服务器接收到 DTO 后,需要将其转换为数据库实体,以便进行数据库操作(如插入、更新等)。因此,就需要定义从 DTO 到实体的反向映射。
  • 从实体到DTO: 在创建或更新数据库记录时,客户端会提交 DTO 数据,服务器需要将这些 DTO 数据转换为实体对象,然后保存到数据库中。如果没有反向映射,就需要手动将 DTO 的属性值赋给实体对象的属性,这会增加代码的复杂度和维护成本。
cs 复制代码
 public class MappingProfile : Profile
 {
     public MappingProfile()
     {
         //实体类转换为dto
         CreateMap<Blog,BlogDto>();
         CreateMap<Post,PostDto>();

         //dto转换为实体类
         CreateMap<BlogDto, Blog>();
         CreateMap<PostDto, Post>();
     }
 }

(3)配置MappingProfile文件

在Program.cs文件中配置AuttoMapper的配置文件

cs 复制代码
//添加auttomapper
builder.Services.AddAutoMapper(typeof(MappingProfile));

(4)控制器编写添加控制器

cs 复制代码
//依赖注入
private readonly ServiceContext _serviceContext;
private readonly IMapper _mapper;
public ServiceController(ServiceContext serviceContext,IMapper mapper)
{
    _serviceContext = serviceContext;
    _mapper = mapper;
}



 //添加博客以及他下面的文章
 [HttpPost("insert")]
 public async Task<IActionResult> Insert([FromBody] BlogDto blogdto)
 {
     Console.WriteLine("------------------------------------");
     try
     {
         var blog = _mapper.Map<Blog>(blogdto);
         foreach (var post in blog.Posts)
         {
             _serviceContext.Posts.Add(post);
         }

         _serviceContext.Blogs.Add(blog);
         await _serviceContext.SaveChangesAsync();
     }
     catch (Exception ex) { 
      return BadRequest(ex.Message);
     }
    
     return Ok("添加成功");
 }

(5)测试

javascript 复制代码
{
    "BlogId": 13,
    "Url": "My Blog",
    "Posts": [
        {
            "PostId": 6,
            "Title": "My First Post",
            "Content": "This is my first post.",
            "BlogId":13
        },
        {
            "PostId": 7,
            "Title": "My Second Post",
            "Content": "This is my second post.",
             "BlogId":13
        }
    ]
}

二、使用自增主键

(1)数据库设置自增

Oracle是没有自增的设置键的,所以要自己写序列和触发器触发

sql 复制代码
--序列
CREATE SEQUENCE POST_SEQ
  START WITH 1
  INCREMENT BY 1
  NOMAXVALUE
  NOCYCLE;
  
  
  CREATE SEQUENCE BLOG_SEQ
  START WITH 1
  INCREMENT BY 1
  NOMAXVALUE
  NOCYCLE;
  
  --触发器 
  CREATE OR REPLACE TRIGGER POST_TRIGGER
  BEFORE INSERT ON POST
  FOR EACH ROW
BEGIN
  SELECT POST_SEQ.NEXTVAL INTO :NEW.POSTID FROM dual;
END;

CREATE OR REPLACE TRIGGER BLOG_TRIGGER
  BEFORE INSERT ON BLOG
  FOR EACH ROW
BEGIN
  SELECT BLOG_SEQ.NEXTVAL INTO :NEW.BLOGID FROM dual;
END;

(2)实体和Dto类

cs 复制代码
  [Table("BLOG")]
  public class Blog
  {
      [Column("BLOGID")]
       //自增
      [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      [Key]
      public int BlodId { get; set; }
      [Column("URL")]
      public string Url { get; set; }

      public ICollection<Post>? Posts { get; set; }
  }
cs 复制代码
 public class BlogDto
 {
     public int BlodId { get; set; }
     public string Url { get; set; }

     public ICollection<PostDto>? Posts { get; set; }
 }
cs 复制代码
 [Table("POST")]
 public class Post
 {
     [Column("POSTID")]
     //自增
     [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
     [Key]
     public int PostId { get; set; }
     [Column("TITLE")]
     public string Title { get; set; }
     [Column("CONTENT")]
     public string Content { get; set; }
     [Column("BLOGID")]
     //可空,因为添加数据时,post是属于当前Blog对象下的,已经知道了BlogId的,在输入数据时没必要  再次输入
     public int? BlogId { get; set; }
     public Blog Blog { get; set; }
 }
cs 复制代码
  public class PostDto
  {
      public int PostId { get; set; }
      public string? Title { get; set; }
      public string Content { get; set; }
      public int? BlogId { get; set; }
  }

(3)控制器

cs 复制代码
 [HttpPost("insert")]
 public async Task<IActionResult> Insert([FromBody] BlogDto? blogdto)
 {
     Console.WriteLine("------------------------------------");
     try
     {
     
         var blog = _mapper.Map<Blog>(blogdto);
        
         foreach (var post in blog.Posts)
         {
             //将当前Blog对象给post对象,让他们关联到
             //在这个forearch中,他是可以改变post的值的
             post.Blog = blog;
             _serviceContext.Posts.Add(post);
         }
        

         _serviceContext.Blogs.Add(blog);
         await _serviceContext.SaveChangesAsync();
     }
     catch (Exception ex) { 
      return BadRequest(ex.Message);
     }
    
     return Ok("添加成功");
 }
相关推荐
勘察加熊人26 分钟前
fastapi房产销售系统
数据库·lua·fastapi
囧囧 O_o42 分钟前
Java 实现 Oracle 的 MONTHS_BETWEEN 函数
java·oracle
m0_7482546643 分钟前
MySQL和SQL server的区别
数据库·mysql
补三补四1 小时前
Yashan DB 实例
数据库·oracle·dba
椰椰椰耶1 小时前
【redis】全局命令set、get、keys
数据库·redis·缓存
月落星还在1 小时前
Redis 内存淘汰策略深度解析
数据库·redis·缓存
左灯右行的爱情1 小时前
Redis- 切片集群
数据库·redis·缓存
LKAI.1 小时前
MongoDB用户管理和复制组
linux·数据库·mongodb
PinkandWhite2 小时前
MySQL复习笔记
数据库·笔记·mysql
熬夜苦读学习2 小时前
库制作与原理
linux·数据库·后端