Golang与ASP.NET Core 6.0 + EF Core 6.0在后端Web开发中的对比分析

Golang与ASP.NET Core 6.0 + EF Core 6.0在后端Web开发中的对比分析 我一直在学习 C# 10 和 .NET 6 生态系统,然而我感觉,尽管付出了巨大努力来最小化这个“框架”,但使用纯 .NET BCL(即使没有 ASP.NET Core)构建的应用程序仍然显得有些臃肿、缓慢且难以配置。C#10 有很多用于编码的新现代特性,但为了向后兼容,仍然保留了 5 年前的旧特性,导致语言本身有些臃肿,对于同一件事有 10 种实现方式,却不清楚哪一种是最优的。

这是我学习 C# 10 和 .NET 6 BCL 一周后的第一印象,我甚至还没开始接触 ASP.NET Core,但根据我现在所学,我感觉要学习这个庞大的平台需要数年时间,才能获得足够的知识和经验来胜任 .NET 后端工程师的入门级工作。

看看我所在地区的招聘信息,Golang 似乎也大量用于后端开发。但它缺乏 ASP.NET Core 6.0 所具有的成熟度,该“框架”拥有许多相互协调的集成功能,与 Node.js 等其他框架相比,减少了很多后端开发带来的麻烦。这是我从社区得到的普遍共识。

你们对此有什么看法?对于后端框架,ASP.NET Core 6.0 与 Golang 相比如何?Golang 是否有像 .NET 的 Entity Framework 那样的 ORM?我对 .NET 这个错综复杂的庞然大物感到非常沮丧,但不确定是否应该放弃目前所学的一切,转而学习一门全新的语言,还是应该坚持使用 .NET,因为我已经学习了一段时间。

编辑:我应该在此帖的上下文中澄清一下,我不仅仅指“GoLang”,更是指 GoLang 的生态系统以及 Go 中流行的后端框架。我不太清楚 Go 中使用的是哪个后端框架,社区对此似乎存在分歧。但在 C# 这边,后端开发基本上只有一个框架(ASP.NET Core)。具体指代 ASP.NET Core 比指代 C# 本身更容易。


更多关于Golang与ASP.NET Core 6.0 + EF Core 6.0在后端Web开发中的对比分析的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

嗯,如果你觉得使用框架更顺手,当然可以用。Web框架、ORM等等,有很多工具可以帮助你用Go进行开发。请查看 https://github.com/avelino/awesome-go

更多关于Golang与ASP.NET Core 6.0 + EF Core 6.0在后端Web开发中的对比分析的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我已经使用Go编程超过一年了。我完成了很多项目。 ASP.NET就是个笑话。 有些人正在将Go的性能与C/C++进行比较。 去读读Go的案例研究吧。我是说,认真读一读。

我不太清楚Go中使用了哪个后端框架。

我刚开始接触Go,并且尽量避免使用框架。我通常对框架的体验是,它们会带来限制,增加很多开销,并且创造一种全新的语言,就像任何类型的ORM所做的那样。到目前为止,我觉得不使用任何框架也很舒服。只需导入任务所需的内容即可。我还没有看到使用框架带来的任何好处。但我不时会听到关于Gin的讨论。

嗨,Dean!

非常感谢你的回答!你的见解非常深刻,虽然你是从.NET Core的角度而非.NET 6来分享你的观点,但你给出的见解量非常棒!

我在社区中也看到过关于使用.NET Core时的类似抱怨,但自从.NET 6发布以来,框架的大小已显著减小,并且与.NET Core相比,似乎更容易使用。当前的.NET生态系统旨在实现模块化,并统一了之前.NET Core的所有不同组件和框架,这可能会也可能不会减少你所提到的混乱情况。

我最近已经做出决定,继续学习.NET 6和C#10,最终目标是学习ASP.NET Core 6.0及其子集——使用React作为前端视图的ASP.NET Core 6.0 MVC。主要原因是,在我所在的地区,.NET开发人员的实习岗位数量明显多于Golang开发人员。我猜主要原因是Golang是一门相当新的语言,许多企业尚未采用。

我根据这个模式制定了一个职业规划,从后端Web开发人员 → DevOps工程师(或QA或CI/CD工程师) → 区块链开发人员(DApps),将从事区块链工作作为我的最终目标。我肯定计划在未来学习和使用Golang。但考虑到我的情况和我所在地区的市场状况,目前这对我来说并不是最合适的选择。

你对此有何看法?与 Golang 相比,ASP.NET Core 6.0 作为后端框架表现如何?

作为一名曾多年专业编写 ASP.NET,并在 .NET Core 发布后转而使用它的人,我觉得自己非常有资格回答这个问题。你认为该框架有多么臃肿/庞大,这个评估似乎完全正确。Microsoft.AspNetCore 命名空间中有一些部分我从未接触过。它非常庞大。我从未觉得可以轻松地深入源码并找到答案,而在 Go 中,当我需要时,我总是可以导航到源码并找到答案。

在定义路由这类东西时,我总是试图更加明确,所以我一直偏爱特性路由,而不是基于约定的路由。因此,在这方面,Go 的各种路由框架完全缺乏"魔法"的特性非常适合我。

总的来说,Go 后端中发生的事情也少得多,这既是好事也是坏事。我曾接手现有的 .NET 项目,有很多次我不得不花时间去弄清楚整个框架到底在做什么(不同的团队使用许多不同的范式)。而在接手现有的 Go 项目时,这种情况尚未发生在我身上。中间件通常是明确的且易于理解,正如我提到的,路由策略也是如此。其缺点是:你"免费"得到的东西更少。但根据我的经验,在大型框架中对"免费"的东西进行故障排除,通常最终花费的时间比仅仅编写简单的、可测试的代码来完成你想做的事情还要多。

在性能方面,与我的 .NET Core 后端相比,我的 Go 后端非常稳定且内存消耗极少。性能不是唯一的衡量标准,真正的性能问题几乎总是出现在不同的层面(数据库,伙计!),但我可以在一个非常小的云实例上部署 Go API 并获得出色的性能。所以,这是值得考虑的一点。

在生产力方面,编写 Go API 时,我真的效率很高。仅仅几年后,我就达到了这样的境界:在使用框架时,我完全不需要思考我在做什么,我只是写代码。因为,再次强调,与 .NET 相比,这里发生的事情更少。在某种程度上,它不那么令人兴奋,但非常高效。

对于没有特定框架要求的客户的新项目,如今我很难想象会选择 Go 以外的任何东西。

Golang 有像 .NET 的 Entity Framework 那样的 ORM 吗?

看看 GORM。它生成的是我用过的所有 ORM 中最干净的 SQL。当我使用 Entity Framework 并尝试进行即使是半高级的查询时,生成的 SQL 会非常糟糕,有时甚至无法工作。我通常构建数据密集型的应用程序,因此对于某些查询,手动编写 SQL 是必要的。但对于 CRUD 和简单的连接(也就是你不想一遍又一遍写的那些无聊的东西)呢?GORM 非常棒。

我对 .NET 这个错综复杂的怪物感到非常沮丧,但不确定是否应该放弃迄今为止所学的一切,转而学习一门全新的语言,还是应该坚持使用 .NET,因为我已经学习了一段时间。

我理解!归根结底,问题在于:你所在地区的人们会付钱让你做什么?你所在地区有很多 Go 的工作机会吗?你计划远程工作吗?我很幸运,有比我所能处理的更多的 Go 工作,但如果我需要工作,并且有人提供给我一份构建 .NET Core 应用程序的合同,我会接受。 微笑表情 我认为这不一定非此即彼。如果你愿意,你可以两者都学。

无论如何,我唯一的其他建议是:尝试一下,为自己构建一个周末项目来使用。构建一个任务跟踪应用程序。一个膳食计划应用程序。什么都行。我想你要么会喜欢它入门和高效生产的便捷性,以及你的后端速度有多快;要么你会不喜欢某些东西有多么冗长。对我来说,它是一个很棒的工具,也是我经常使用的工具。我喜欢这门语言、社区和生态系统。

Go与ASP.NET Core 6.0 + EF Core对比分析

语言特性对比

Go的核心优势:

// Go的简洁性示例
package main

import (
    "encoding/json"
    "net/http"
)

type User struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
}

func main() {
    http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
        users := []User{{ID: 1, Name: "John"}}
        json.NewEncoder(w).Encode(users)
    })
    http.ListenAndServe(":8080", nil)
}

C#的多样性:

// C#有多种实现方式
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

// 方式1:传统属性
// 方式2:记录类型(record)
// 方式3:结构体(struct)
// 方式4:匿名类型
// 方式5:元组

Go的Web框架生态

主流选择:

  1. 标准库net/http(最常用)
  2. Gin(高性能轻量级框架)
  3. Echo(极简框架)
  4. Fiber(Express风格)

Gin框架示例:

package main

import "github.com/gin-gonic/gin"

func main() {
    r := gin.Default()
    
    r.GET("/users", func(c *gin.Context) {
        c.JSON(200, gin.H{
            "users": []map[string]interface{}{
                {"id": 1, "name": "Alice"},
            },
        })
    })
    
    r.Run(":8080")
}

Go的ORM选择

主要ORM:

  1. GORM(最流行,功能完整)
  2. sqlx(轻量级扩展)
  3. ent(Facebook出品,代码生成)
  4. sqlc(类型安全,SQL优先)

GORM示例:

package main

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
)

type Product struct {
    gorm.Model
    Code  string
    Price uint
}

func main() {
    dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920"
    db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }
    
    // 自动迁移
    db.AutoMigrate(&Product{})
    
    // 创建记录
    db.Create(&Product{Code: "D42", Price: 100})
    
    // 查询
    var product Product
    db.First(&product, "code = ?", "D42")
}

性能对比

Go的并发模型:

// Goroutine轻量级并发
func handleRequest(w http.ResponseWriter, r *http.Request) {
    go processAsync(r) // 启动goroutine
    w.Write([]byte("Processing"))
}

func processAsync(r *http.Request) {
    // 异步处理逻辑
    time.Sleep(2 * time.Second)
    fmt.Println("Processed:", r.URL.Path)
}

内存占用对比:

  • Go编译为静态二进制文件,部署简单
  • .NET需要运行时环境
  • Go应用通常内存占用更低

开发体验

Go的工具链:

# 简单直接的开发流程
go mod init myapp
go get github.com/gin-gonic/gin
go run main.go
go build -o myapp

依赖管理:

// go.mod文件示例
module myapp

go 1.19

require (
    github.com/gin-gonic/gin v1.8.1
    gorm.io/gorm v1.24.0
)

学习曲线

Go的学习路径:

  1. 语言基础(1-2周)
  2. 标准库(1周)
  3. 常用框架(1-2周)
  4. 数据库操作(1周)

项目结构示例:

myapp/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   ├── handlers/
│   ├── models/
│   └── database/
├── pkg/
├── go.mod
└── go.sum

就业市场分析

Go后端常见场景:

  1. 微服务架构
  2. API网关
  3. 高并发系统
  4. 云原生应用
  5. DevOps工具

技术栈示例:

// 完整的微服务示例
package main

import (
    "context"
    "log"
    "net/http"
    "time"
    
    "github.com/gin-gonic/gin"
    "go.uber.org/zap"
    "gorm.io/gorm"
)

type Server struct {
    router *gin.Engine
    db     *gorm.DB
    logger *zap.Logger
}

func NewServer() *Server {
    return &Server{
        router: gin.Default(),
        logger: zap.NewExample(),
    }
}

func (s *Server) Start() error {
    s.setupRoutes()
    return s.router.Run(":8080")
}

迁移建议

从C#到Go的对应关系:

  • ASP.NET Core Controller → Gin Handler
  • EF Core → GORM
  • LINQ → 手动查询或第三方库
  • Dependency Injection → 手动注入或wire
  • Middleware → Gin中间件

中间件示例:

func Logger() gin.HandlerFunc {
    return func(c *gin.Context) {
        start := time.Now()
        c.Next()
        latency := time.Since(start)
        log.Printf("%s %s %v", c.Request.Method, c.Request.URL.Path, latency)
    }
}

func main() {
    r := gin.New()
    r.Use(Logger())
    // ...路由配置
}

Go在后端开发中提供了更简单的抽象、更快的编译速度、更低的内存占用和更平缓的学习曲线。虽然生态系统不如.NET成熟,但对于新项目和高并发场景具有明显优势。

回到顶部