草庐IT

chatGPT帮助开发实战解答问题和反思

广州宁骑 2023-03-28 原文

 

问题来自.Net开发群友

 

问题

我想做一个自动生成单据号的功能,但是在EFCORE里没有行级锁,请有什么等价方案吗?

 

ChatGPT回答

在 EF Core 中确实没有提供行级锁(row-level locking)的功能,因为这需要对数据库进行显式的锁定操作,而 EF Core 的设计理念是尽可能不与数据库直接交互,而是通过抽象层面的数据操作来实现,因此不鼓励使用显式的锁定操作。

不过,在 EF Core 中提供了乐观并发控制(Optimistic Concurrency Control)的功能,可以用于处理类似于行级锁的需求。乐观并发控制基于版本号(Version)机制实现,每个实体对象都有一个版本号属性,当两个用户同时更新同一个实体对象时,EF Core 会比较它们的版本号,如果版本号不一致,则表示有冲突发生,需要执行相应的冲突解决逻辑。

因此,如果你想实现自动生成单据号的功能,并保证其唯一性,可以考虑使用乐观并发控制的方案。具体的实现思路如下:

  1. 在你的实体对象中增加一个版本号属性,类型为整数。

  2. 在生成单据号前,使用 EF Core 查询最后一条记录的单据号和版本号,得到最新的单据号和版本号。

  3. 在生成单据号时,将版本号加 1,并将单据号和版本号写入到新的记录中。如果写入数据库时发生冲突,则表示有其他用户同时在生成单据号,此时可以重新获取最新的单据号和版本号,并再次尝试生成。

以下是一个简单的示例代码,演示了如何使用乐观并发控制来生成唯一的单据号

public class Order
{
    public int Id { get; set; }
    public string OrderNo { get; set; }
    public int Version { get; set; }
}

public class OrderContext : DbContext
{
    public DbSet<Order> Orders { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Order>()
            .Property(o => o.Version)
            .IsConcurrencyToken();
    }
}

public class OrderService
{
    private readonly OrderContext _context;

    public OrderService(OrderContext context)
    {
        _context = context;
    }

    public string GenerateOrderNo()
    {
        string lastOrderNo = _context.Orders
            .OrderByDescending(o => o.Id)
            .Select(o => o.OrderNo)
            .FirstOrDefault();

        int lastVersion = _context.Orders
            .OrderByDescending(o => o.Id)
            .Select(o => o.Version)
            .FirstOrDefault();

        string newOrderNo = GenerateNewOrderNo(lastOrderNo);

        var order = new Order
        {
            OrderNo = newOrderNo,
            Version = lastVersion + 1
        };

        _context.Orders.Add(order);

        try
        {
            _context.SaveChanges();
        }
        catch (DbUpdateConcurrencyException ex)
        {
            // 处理并发冲突
            ex.Entries.Single().Reload();
            lastOrderNo = _context.Orders
                .OrderByDescending(o => o.Id)
                .Select(o=> o.OrderNo) .FirstOrDefault(); lastVersion = _context.Orders .OrderByDescending(o => o.Id) .Select(o => o.Version) .FirstOrDefault(); newOrderNo = GenerateNewOrderNo(lastOrderNo); order.OrderNo = newOrderNo; order.Version = lastVersion + 1; _context.SaveChanges(); } return newOrderNo; } private string GenerateNewOrderNo(string lastOrderNo) { // 生成新的单据号逻辑 // ... }
}

 

反思

EFCORE 和 行级锁,如果提问者不知道这两者的含义根本没法问,就算问了,回答的东西,所以chatGPT对提问者也是有要求的

再没有chatGPT以前,我们码农如果遇到这个问题如何解决了?

很简单,使用各种搜索引擎,或者询问同行,搜集零碎的信息然后最终拼凑起来

程序员在有了chatGPT之后,有什么变化?

显而易见,缩短了搜索的时间

总结

其实不管是以前的面向搜索引擎编程,还是面向群友编程,其实都在暗中隐喻了程序员的未来——架构师

开发软件应用,最终是为了人类某个行业提供多一种可选方式

(例如外卖,古代也有外卖,让店小二提餐走路送去大户人家家里

  后来有了马车,单车,直到现在的摩托车,什么变了?方式变了,最终目的并没有改变

做开发其实也是一个道理,我们并不是做一个XX软件去替代,而是为了原本的最终目的提供多一种方式,而程序员则是这多出来的一种方式的设计师,让这个新的方式更加的容易被大众接纳和方便使用

要不然,我原本方式很简单,为什么要用你给我提供的方式呢?近些年开发行业也经常出现这种本末倒置的情况,很多码农都不知道自己开发这些软件应用的目的到底是为什么,对于我们开发者而言

不管什么技术,只是为了达成最终目的的手段,而不是最终目的

 

这也是我实在不喜欢背诵一些照本宣科的书面理论知识,而是更热衷提出和发现程序的到设计思路

说了这么多只是想说,程序员的未来肯定会是架构师,我们所有的技术积累我个人看来只是为了让我们的思维从普通人转换成程序员思维,而且我相信在未来,编程思维会如同吃饭一样,成为每个人的必备

 

有关chatGPT帮助开发实战解答问题和反思的更多相关文章

  1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

    尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

  3. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

    我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

  5. ruby - Fast-stemmer 安装问题 - 2

    由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

  6. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  7. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  8. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  9. ruby - 是否可以覆盖 gemfile 进行本地开发? - 2

    我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI

  10. ruby - 在 Windows 机器上使用 Ruby 进行开发是否会适得其反? - 2

    这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby​​-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub

随机推荐