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("添加成功");
 }
相关推荐
dovens1 分钟前
PostgreSQL 中进行数据导入和导出
大数据·数据库·postgresql
IOT.FIVE.NO.11 分钟前
claude code desktop cowork报错解决和记录Workspace..The isolated Linux environment ...
linux·服务器·数据库
Rick199310 分钟前
mysql 慢查询怎么快速定位
android·数据库·mysql
科技小花7 小时前
全球化深水区,数据治理成为企业出海 “核心竞争力”
大数据·数据库·人工智能·数据治理·数据中台·全球化
X56618 小时前
如何在 Laravel 中正确保存嵌套动态表单数据(主服务与子服务)
jvm·数据库·python
虹科网络安全9 小时前
艾体宝干货|数据复制详解:类型、原理与适用场景
java·开发语言·数据库
2301_7717172110 小时前
解决mysql报错:1406, Data too long for column
android·数据库·mysql
小江的记录本10 小时前
【Kafka核心】架构模型:Producer、Broker、Consumer、Consumer Group、Topic、Partition、Replica
java·数据库·分布式·后端·搜索引擎·架构·kafka
dvjr cloi10 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql
dFObBIMmai11 小时前
MySQL主从同步中大事务导致的延迟_如何拆分大事务优化同步
jvm·数据库·python