1.ASP.NET Core + EF实现Api接口

1.示例简介

公司会有很多网站,我们可以把这些网站地址都配置在数据库中,在公司的门户网站上显示出来,这样用户就只要登录门户网站就行,用户可以通过点击门户网站的图标来访问其他的网站,该案例最终效果图如下

首页系统配置.gif

2.创建一个ASP.NET Core WebApi项目

image

项目创建成功后,打开Properties\launchSettings.json文件,把端口号设置为5000

因为使用的是SqlServer数据库,这里需要添加EntityFrameworkCore包和EntityFrameworkCore.SqlServer包

Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer

项目结构如下图


image.png

3.使用EF和数据库建立连接

3.1 数据表

该示例用到三张表,在每个表中都插入了一些数据
Base_DataDictionary:数据字典表


image.png

Base_DataDictionaryDetail:数据字典详细表,这个表的ParentId就是上面表的Id


image.png

Base_Setting:用户配置表,存储用户在首页上显示的图标


image.png

3.2 Entities

在项目中新建Entities文件夹,该文件夹用来存放与数据表一一对应的实体类,根据数据结构,创建下面4个实体类

EntityBase:这个实体用来存放数据表都有的一些基础字段

public abstract class EntityBase
{
    [Key]
    public Guid Id { get; set; }
    public bool IsDelete { get; set; }
    public Guid? ParentId { get; set; }
    public DateTime? CreateTime { get; set; }
    public Guid? CreateUserId { get; set; }
    public DateTime? ModifyTime { get; set; }
    public Guid? ModifyUserId { get; set; }
}

DataDictionary

[Table("Base_DataDictionary")]
public class DataDictionary : EntityBase
{
    public string Code { get; set; }
    public string FullName { get; set; }
    public string ShortName { get; set; }
    public int? SortCode { get; set; }
    public virtual ICollection<DataDictionaryDetail> Details { get; set; }
}

DataDictionaryDetail

[Table("Base_DataDictionaryDetail")]
public class DataDictionaryDetail : EntityBase
{
    public string Code { get; set; }
    public string FullName { get; set; }
    public string ShortName { get; set; }
    public int? SortCode { get; set; }
    [Column("Ext1")]
    public string ImagePath { get; set; }

    [Column("Ext2")]
    public string RedirectUrl { get; set; }
    public virtual DataDictionary Dictionary { get; set; }
}

Setting

[Table("Base_Seeting")]
public class Setting
{
    [Key]
    public Guid Id { get; set; }
    public Guid? DetailId { get; set; }
    public Guid? UserId { get; set; }
    public int? SortCode { get; set; }
    [NotMapped]
    public bool IsDelete { get; set; }
}

3.3 DbContext实现

在项目中新建Context文件夹,用来存放数据库上下文,在Context文件夹下新建\color{red}{PortalContext}类,代码如下

public class PortalContext : DbContext
{
    public DbSet<DataDictionary> DataDictionaries { get; set; }
    public DbSet<DataDictionaryDetail> DataDictionaryDetails { get; set; }
    public DbSet<Setting> Settings { get; set; }

    public PortalContext(DbContextOptions<PortalContext> options)
        : base(options)
    {
    }    
}

然后我们需要添加一下2张表的映射关系,这两张表之间是一对多的关系,我们在重写OnModelCreating方法中添加如下代码建立两张表的联系

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<DataDictionary>()
        .HasMany(data => data.Details)
        .WithOne(dataDetail => dataDetail.Dictionary)
        .HasForeignKey(dataDetail => dataDetail.ParentId);
}

3.4 把PortalContext注入到DI系统中

在Startup.cs中的ConfigureServices方法中添加如下代码

services.AddDbContext<PortalContext>(builder =>
{
    string connString = Configuration.GetConnectionString("DefaultConnection");
    builder.UseSqlServer(connString);
});

DefaultConnection配置在appsettings.json文件中

"ConnectionStrings": {
  "DefaultConnection": "Data Source=LAPTOP-1UNDDFV3\\SQLEXPRESS;Initial Catalog=Portal_DB;Integrated Security=True"
}

到这里已经完成了基本的编码工作了,下面就是在Controller中获取和修改数据了

4.获取和修改数据

我们在框架默认创建的Values控制器中添加_context字段,并且注入上面创建的\color{red}{PortalContext}上下文

private readonly PortalContext _context;

public ValuesController(PortalContext context)
{
    _context = context;
}

4.1 获取数据

在Get方法中,该方法接收一个parentId和userId参数,用来获取该parentId下的所有图标,其中用户要显示在首页的图标使用左外连接来区分(即enable列表),代码如下

[HttpGet]
public JsonResult Get(string parentId, string userId)
{
    var details = (from d in _context.DataDictionaryDetails
                    join s in _context.Settings
                    on new { detailId = d.Id, userId = new Guid(userId) } equals new { detailId = s.DetailId.Value, userId = s.UserId.Value } into setting
                    from s in setting.DefaultIfEmpty()
                    where d.ParentId.ToString() == parentId
                    orderby s.SortCode
                    select new
                    {
                        d.Id,
                        d.Code,
                        d.FullName,
                        d.ShortName,
                        d.ImagePath,
                        d.RedirectUrl,
                        Setting = s
                    }).ToList();
    return Json(new
    {
        enable = details.Where(_ => _.Setting != null),
        notEnable = details.Where(_ => _.Setting == null)
    });
}

4.2 修改数据

在Post方法中,该方法有一个\color{red}{IEnumerable<Setting>}类型的集合,遍历该集合,如果集合中某个Setting的IsDelete为true,则删除该条数据;如果Setting的Id为null,则新增;否则为修改,代码如下

[HttpPost]
public bool Post(IEnumerable<Setting> settings)
{
    foreach (Setting setting in settings)
    {
        if (setting.IsDelete)
        {
            _context.Settings.Remove(setting);
        }
        else if (setting.Id == Guid.Empty)
        {
            setting.Id = Guid.NewGuid();
            _context.Settings.Add(setting);
        }
        else
        {
            EntityEntry<Setting> entityEntry = _context.Entry(setting);
            entityEntry.State = EntityState.Modified;
            entityEntry.Property(e => e.DetailId).IsModified = false;
            entityEntry.Property(e => e.UserId).IsModified = false;
        }
    }

    return _context.SaveChanges() > 0;
}

5.测试接口

运行项目,在浏览器中输入http://localhost:5000/api/values?parentId=ACB951B9-EA43-4F71-9E45-081229E3F26A&userId=FBAD9A6E-89D1-49E9-9CBD-F1D04C67443A,就可以看到Get方法返回的数据

image.png

在PostMan中,调用Post方法来修改一条数据和新增一条数据,把id为E2B44D59-94C1-4AC1-9707-511F3C79A0B7的这条数据的SortCode修改为3;新增一条DetailId为5B9E490D-DEC4-40D8-88BC-340EE919F2F3,SortCode为0的数据,可以看到接口返回true


image.png

再次调用Get方法,可以看到enables数组里Id为E2B44D59-94C1-4AC1-9707-511F3C79A0B7的数据的SortCode正确修改为3,并且也成功添加了一条数据


image.png

git仓库地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容