如何使用 FreeSql 无缝接替 EF Core ?

news2024/11/25 0:35:27

如何使用 FreeSql 无缝接替 EF Core,并实现数据表的 CRUD 操作

  • 项目说明
  • DB & 数据表结构
    • DB & 数据表创建
    • 数据表 User 实体模型创建
  • 使用 EF Core 实现 User 表新增用户信息
    • 添加 EF Core 相关的 nuget 包
    • 编写 EF Core 操作 User 表的 CRUD 代码
  • FreeSql 使用 DbContext 接替 EF Core
    • 单例对象构造器 SingletonConstructor
    • 使用 SingletonConstructor 构建 IFreeSql
    • 反射解析 DatabaseFacade
      • EF Core 中 DbContext 官方定义
      • EF Core 中 DatabaseFacade 官方定义
      • 反射解析对象 DatabaseFacade
  • 测试 orm 两种模式下的操作
    • 添加 User 用户信息
    • FreeSql 查询 User 用户信息
  • 总结

Gradual evolution

项目说明

  • 实现目标:使用 FreeSql 无缝接替 EF Core,并实现数据表的 CRUD 操作;

接下来我们先回顾下 EF Core 中如何实现数据表的 CRUD 操作,在操作之前我们先把数据库和相关表结构准备好。

DB & 数据表结构

  • 数据库实例名称:Test
  • 数据表结构:User

此处为了方便演示,创建一个简单的 User 表,数据结构如下:

字段说明
Id主键,用户ID
Name用户姓名

DB & 数据表创建

创建数据库实例 TestUser 表,执行如下 sql 脚本:

USE master;  
GO  

-- 创建 Test
CREATE DATABASE Test  
ON   
( NAME = Test_dat,  
    FILENAME = 'D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\testdat.mdf',  
    SIZE = 10,  
    MAXSIZE = 50,  
    FILEGROWTH = 5 )  
LOG ON  
( NAME = Test_log,  
    FILENAME = 'D:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA\testlog.ldf',  
    SIZE = 5MB,  
    MAXSIZE = 25MB,  
    FILEGROWTH = 5MB );  
GO

CREATE TABLE Test.dbo.[User] (
	Id varchar(36) NOT NULL primary key,
	Name varchar(20) NOT NULL
);
EXEC Test.sys.sp_addextendedproperty 'MS_Description', N'用户信息', 'schema', N'dbo', 'table', N'User';
GO

执行上面 sql 脚本创建数据库失败时,可以先执行如下 sql 脚本,然后在继续执行上面步骤。

-- 关闭数据库连接并删除数据库
ALTER DATABASE Test SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE Test;

除了上面常规的 mssql 配置,开发环境为了方便快捷,还可以使用 Docker 运行 mssql 镜像(mcr.microsoft.com/mssql/server),此处我是配置的 Docker 环境(这里不做详细介绍,感兴趣的小伙伴自行查看资料):

docker-mssql

到这里我们就把基本的开发环境准备好了,接下来就是新建项目相关环节的操作。

数据表 User 实体模型创建

依据上面的 User 表结构,在(新建)项目 Jeff.Mes.EntityFrameworkCore 中添加 C# 模型类:

using System.ComponentModel.DataAnnotations.Schema;

namespace Jeff.Mes.EntityFrameworkCore;

/// <summary>
/// 用户信息表
/// </summary>
[Table("User")]
public class User
{
    /// <summary>
    /// 主键,用户ID 
    /// </summary>
    public string Id { get; set; }
    /// <summary>
    /// 用户姓名
    /// </summary>
    public string Name { get; set; }
}

使用 EF Core 实现 User 表新增用户信息

上面我们准备好 Test 数据库、User 表和 C# 实体模型结构 后,接下来准备编写 EF Core 相应的操作代码。

添加 EF Core 相关的 nuget 包

说明:此处环境使用的 SqlServer 数据库,其他类型的数据库需添加相应的 nuget 包。

接着我们继续在上面新建的项目【Jeff.Mes.EntityFrameworkCore】中改造,添加 nuget 包:

  • Microsoft.EntityFrameworkCore.SqlServer
NuGet\Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 6.0.14

efcore.sqlserver

编写 EF Core 操作 User 表的 CRUD 代码

项目【Jeff.Mes.EntityFrameworkCore】中添加 FreeSqlNuget 包:

  • FreeSql.Provider.SqlServer
NuGet\Install-Package FreeSql.Provider.SqlServer -Version 3.2.687

FreeSql.Provider.SqlServer

在项目【Jeff.Mes.EntityFrameworkCore】中新建 TestContext 类,继承 DbContext,实现如下:

using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema;

namespace Jeff.Mes.EntityFrameworkCore;

/// <summary>
/// Test 数据库上下文对象
/// </summary>
public class TestContext : DbContext
{
    public TestContext() { }
 
    /// <summary>
    /// 用户信息表
    /// </summary>
    public virtual DbSet<User> User { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            // db 连接字符串,其中符号 “***” 代表数据库访问密码
            string dbConnString = "Data Source=.;Initial Catalog=Test;Persist Security Info=True;User ID=sa;Password=***";
            optionsBuilder.UseSqlServer(dbConnString);
        }
    }

    /// <summary>
    /// 【EF Core 模式】添加用户测试
    /// </summary>
    /// <returns></returns>
    public async Task<int> AddUserAsync()
    {
        using (var dbContext = new TestContext())
        {
            var guid = Guid.NewGuid().ToString();
            var user = new User
            {
                Id = guid,
                Name = $"efcore-{guid.Substring(0, 5)}"
            };
            dbContext.Add(user);
            return await dbContext.SaveChangesAsync();
        }
    }

    // 注意对比下面的,【FreeSql 模式】添加用户测试
}

上面操作 User 表的 CRUD 代码,为了简化此处只写 AddUserAsync 添加操作,其他代码就不在详细介绍。

FreeSql 使用 DbContext 接替 EF Core

Entity Framework(简称 EF) 中创建模型后,应用程序所交互的主要类是 System.Data.Entity.DbContext(通常称为 上下文类 )。默认情况下,上下文管理与数据库的连接。

单例对象构造器 SingletonConstructor

单例对象构造器 SingletonConstructor 代码如下:

namespace Jeff.Mes.Common;

/// <summary>
/// 单例对象构造器
/// </summary>
/// <typeparam name="T"></typeparam>
public class SingletonConstructor<T> where T : class, new()
{
    private static T? _Instance;
    private readonly static object _lockObj = new();

    /// <summary>
    /// 获取单例对象的实例
    /// </summary>
    /// <returns></returns>
    public static T GetInstance()
    {
        if (_Instance != null) return _Instance;
        lock (_lockObj)
        {
            if (_Instance == null)
            {
                var item = System.Activator.CreateInstance<T>();
                System.Threading.Interlocked.Exchange(ref _Instance, item);
            }
        }
        return _Instance;
    }
}

使用 SingletonConstructor 构建 IFreeSql

新建 FreeSqlHelper.cs 文件,使 FreeSqlHelper 类继承自 SingletonConstructor 单例构造器,代码示例如下:

using System.Collections.Concurrent;
using FreeSql;
using Jeff.Mes.Common;

namespace Jeff.Mes.DbHelper;

/// <summary>
/// 【Singleton 单例模式】构建 freesql 对象
/// </summary>
public sealed class FreeSqlHelper : SingletonConstructor<FreeSqlHelper>
{
    //连接字符串作为 key,存储构建的 IFreeSql 对象的字典集合
    private readonly static ConcurrentDictionary<string, IFreeSql> _FreeDic = new();

    #region 构建 freesql 对象
    public IFreeSql? FreeBuilder(string dbType, string connStr)
    {
        if (string.IsNullOrWhiteSpace(dbType) || string.IsNullOrWhiteSpace(connStr))
        {
            return default;
        }

        bool isOk = _FreeDic.TryGetValue(connStr, out IFreeSql? fsql);
        if (isOk)
        {
            return fsql;
        }

        DataType dataType;
        string myDbType = dbType.Contains('.') ? dbType.Substring(dbType.LastIndexOf('.') + 1) : dbType;
        switch (myDbType.ToLower())
        {
            case "mysql":
                dataType = DataType.MySql;
                break;

            default:
                dataType = DataType.SqlServer;
                break;
        }

        return FreeBuilder(dataType, connStr);
    }

    public IFreeSql? FreeBuilder(DataType dbType, string connStr)
    {
        if (string.IsNullOrWhiteSpace(connStr))
        {
            return default;
        }

        /*
        bool hasKey = _FreeDic.ContainsKey(connStr);
        if (hasKey)
        {
            return _FreeDic[connStr];
        }*/

        bool isOk = _FreeDic.TryGetValue(connStr, out IFreeSql? fsql);
        if (isOk)
        {
            return fsql;
        }

        fsql = new FreeSqlBuilder()
                    .UseConnectionString(dbType, connStr)
                    .UseAutoSyncStructure(false) //自动同步实体结构到数据库
                    .Build(); //请务必定义成 Singleton 单例模式 

        bool isAdd = _FreeDic.TryAdd(connStr, fsql);
        if (isAdd)
        {
            return fsql;
        }
        else
        {
            fsql.Dispose();
            return _FreeDic[connStr];
        }
    }

    public (bool isOk, IFreeSql? fsql) GetFreeSql(DataType dbType, string connStr)
    {
        bool isOk = _FreeDic.TryGetValue(connStr, out IFreeSql? fsql);
        if (!isOk)
        {
            fsql = FreeBuilder(dbType, connStr);
            isOk = fsql != null;
        }
        return (isOk, fsql ?? default);
    }
    #endregion
}

使用 FreeSqlHelper 对象构建 IFreeSql,如下代码:

 IFreeSql fsql = FreeSqlHelper.GetInstance().FreeBuilder(dbType, connStr);

上面环节我们就准备好了 IFreeSql 对象的构建,万事俱备,只欠东风(下面我们解析解析 DbContext 获取有效信息);

反射解析 DatabaseFacade

在反射解析 DbContext 对象之前,我们先回顾下相关概念定义和类库基本信息。

EF Core 中 DbContext 官方定义

  • Microsoft.EntityFrameworkCore.DbContext

上面我简单的介绍了 DbContextEF Core数据库连接对象,接下来我们看下官方定义:

  • 命名空间:Microsoft.EntityFrameworkCore
  • 程序集:Microsoft.EntityFrameworkCore.dll
  • Nuget 包:Microsoft.EntityFrameworkCore v7.0.0

DbContext 实例表示与数据库的会话,可用于查询和保存实体的实例。 DbContext 是工作单元和存储库模式的组合。

public class DbContext : IAsyncDisposable, 
IDisposable, Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<IServiceProvider>, 
Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies, 
Microsoft.EntityFrameworkCore.Internal.IDbContextPoolable, 
Microsoft.EntityFrameworkCore.Internal.IDbSetCache

关于 DbContext 更多信息,请查看 =》https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.entityframeworkcore.dbcontext?view=efcore-7.0

EF Core 中 DatabaseFacade 官方定义

  • Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade

DatabaseFacade 类定义如下:

  • 命名空间:Microsoft.EntityFrameworkCore.Infrastructure
  • 程序集:Microsoft.EntityFrameworkCore.dll
  • Nuget 包:Microsoft.EntityFrameworkCore v7.0.0

提供对上下文的数据库相关信息和操作的访问。 此类的实例通常是从 Database 中获取的,它不是在应用程序代码中直接构造的。

public class DatabaseFacade : 
Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<IServiceProvider>, 
Microsoft.EntityFrameworkCore.Infrastructure.IResettableService, 
Microsoft.EntityFrameworkCore.Storage.IDatabaseFacadeDependenciesAccessor

关于 DatabaseFacade 更多信息,请查看 =》https://learn.microsoft.com/zh-cn/dotnet/api/microsoft.entityframeworkcore.infrastructure.databasefacade?view=efcore-7.0

反射解析对象 DatabaseFacade

  • Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade

添加反射解析 DatabaseFacade 对象的代码:

/// <summary>
/// 根据对象实例和属性名称获得属性值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="obj"></param>
/// <param name="property"></param>
/// <returns></returns>
public static T? GetProperty<T>(this object obj, string property)
{
    var result = default(T);
    try
    {
        var t = obj.GetType();
        var propertyObj = t.GetProperty(property)?.GetValue(obj, null);
        result = (T?)propertyObj.ChangeType(typeof(T));
        return result;
    }
    catch(Exception ex)
    {
        throw ex;
    }
}

/// <summary>
/// 类型转换
/// </summary>
/// <param name="value"></param>
/// <param name="type"></param>
/// <returns></returns>
public static object? ChangeType(this object? value, Type type)
{
    if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
    if (value == null) return null;
    if (type == value.GetType()) return value;
    if (type.IsEnum)
    {
        if (value is string valEnum) return Enum.Parse(type, valEnum);
        else return Enum.ToObject(type, value);
    }
    if (!type.IsInterface && type.IsGenericType)
    {
        Type innerType = type.GetGenericArguments()[0];
        object? innerValue = ChangeType(value, innerType);
        return Activator.CreateInstance(type, new object?[] { innerValue });
    }
    if (value is string valGuid && type == typeof(Guid)) return new Guid(valGuid);
    if (value is string valVersion && type == typeof(Version)) return new Version(valVersion);
    if (value is Guid && type == typeof(string)) return value.ToString();
    if (value is not IConvertible) return value;

    if (type.IsGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
    {
        var underlyingType = Nullable.GetUnderlyingType(type);
        type = underlyingType ?? type;
    } // end if
    return Convert.ChangeType(value, type);
}

继续在 TestContext.cs 类中添加如下代码:

/// <summary>
/// 【FreeSql 模式】添加用户测试
/// </summary>
/// <returns></returns>
public async Task<int> FreeSqlAddUserAsync()
{
    using (var dbContext = new TestContext())
    {
        var (myDbContext, fsql) = GetDbContext(dbContext);

        var guid = Guid.NewGuid().ToString();
        var user = new User
        {
            Id = guid,
            Name = $"fsql-{guid.Substring(0, 5)}"
        };

        // fsql.Insert(user).AsTable("User").ExecuteAffrowsAsync();
        return await fsql.Insert(user).ExecuteAffrowsAsync();
    }
}

/// <summary>
/// 反射获取信息,并构建 FreeSql
/// </summary>
/// <param name="dbContext"></param>
/// <returns></returns>
public (DbContext dbContext, IFreeSql fsql) GetDbContext(DbContext dbContext)
{
    /*
    ((EQuality.Framework.Dal.EFDbContext)_IDbContext).ConnStr
    ((Microsoft.EntityFrameworkCore.DbContext)ss).Database.ProviderName
    */

    //-	Database	
    // {Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade}	
    // Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade
    var dbFacade = dbContext.GetProperty<DatabaseFacade>("Database");
    string dbType = dbFacade.ProviderName; // db 类型
    string connStr = dbContext.Database.GetConnectionString(); // 获取 db 连接字符串
    IFreeSql fsql = FreeSqlHelper.GetInstance().FreeBuilder(dbType, connStr); // 单例构造器构建 IFreeSql 对象 

    return (dbContext, fsql);
}

此处项目【Jeff.Mes.EntityFrameworkCore】中 TestContext.cs 类已经完成两种 orm 模式下新增 User 信息的操作,分别是:

  • AddUserAsync,【EF Core 模式】添加用户测试;
  • FreeSqlAddUserAsync,【FreeSql 模式】添加用户测试;

到这里我们就可以使用 FreeSql 无缝替换 EF Core 的操作,同时也保留了 EF Core 模式的玩法,小伙伴们又可以继续愉快的玩耍了哟。

测试 orm 两种模式下的操作

添加 User 用户信息

新增控制台项目【Jeff.Mes.EntityFrameworkCore.Test】,项目引用【Jeff.Mes.EntityFrameworkCore】,添加如下代码:

namespace Jeff.Mes.EntityFrameworkCore.Test;

internal class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Hello, EF Core & FreeSQL!");

        var test = new TestContext();
        int rcount1 = await test.AddUserAsync();
        string info1 = rcount1 > 0 ? "User 信息添加成功" : "User 信息添加失败";
        Console.WriteLine($"efcore 模式:{info1}");

        int rcount2 = await test.FreeSqlAddUserAsync();
        string info2 = rcount2 > 0 ? "User 信息添加成功" : "User 信息添加失败";
        Console.WriteLine($"fsql 模式:{info2}");

        Console.ReadKey();
    }
}

使用 vs 【工具 => 连接到数据库】测试数据库连接是否能正常通信访问,测试如下:

vs 连接数据库

启动控制台,执行代码,输出如下信息:

Hello, EF Core & FreeSQL!
efcore 模式:User 信息添加成功
fsql 模式:User 信息添加成功

控制台测试

使用数据库客户端工具 DBeaver 查看:

user表数据

FreeSql 查询 User 用户信息

使用 FreeSQL 查询 User 表信息:

/// <summary>
/// 【FreeSql 模式】查询用户信息
/// </summary>
/// <returns></returns>
public async Task<List<User>> FreeSqlGetUserAsync()
{
    using (var dbContext = new TestContext())
    {
        var (myDbContext, fsql) = GetDbContext(dbContext);
        return await fsql.Select<User>().ToListAsync();
    }
}

控制台 Main 函数中调用 FreeSqlGetUserAsync 方法:

fsql 查询 user 信息

关于 FreeSql 更多信息,请查看相关文档

  • FreeSql 官方文档,https://freesql.net/
  • FreeSql 博客文档,https://www.cnblogs.com/FreeSql/p/11531300.html

总结

在使用 EF Core 作为默认的 ORM 工具操作数据库时,项目中我们或许只能接触到 DbContext 对象,没法直接获取 db 数据库连接信息,假如有小伙伴想接入 FreeSQL 继续使用熟悉的模式,那该怎么办呢?此时我们可以这样操作,为了不影响原有项目结构的操作,又想接入 FreeSQL 的小伙伴们,通过上面的方式我们就可以使用 FreeSQL 无缝替换 EF Core

其实接入 FreeSQL 的方式很简单,只需具备两点条件即可,首先就是 有效的 db 连接字符串dbContext.Database.GetConnectionString()】,其次就是获取对应的 数据库类型dbFacade.ProviderName】。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/373732.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

系统启动太慢,调优后我直呼Nice

问题背景最近在负责一个订单系统的业务研发&#xff0c;本来不是件困难的事。但是服务的启动时间很慢&#xff0c;慢的令人发指。单次启动的时间约在10多分钟左右&#xff0c;基本一次迭代、开发&#xff0c;大部分的时间都花在了启动项目上。忍无可忍的我&#xff0c;终于决定…

链路追踪——【Brave】第一遍小结

前言 微服务链路追踪系列博客&#xff0c;后续可能会涉及到Brave、Zipkin、Sleuth内容的梳理。 Brave 何为Brave&#xff1f; github地址&#xff1a;https://github.com/openzipkin/brave Brave是一个分布式追踪埋点库。 #mermaid-svg-riwF9nbu1AldDJ7P {font-family:"…

大数据Hadoop教程-学习笔记05【Apache Hive DML语句与函数使用】

视频教程&#xff1a;哔哩哔哩网站&#xff1a;黑马大数据Hadoop入门视频教程 总时长&#xff1a;14:22:04教程资源: https://pan.baidu.com/s/1WYgyI3KgbzKzFD639lA-_g 提取码: 6666【P001-P017】大数据Hadoop教程-学习笔记01【大数据导论与Linux基础】【17p】【P018-P037】大…

一文带你搞定线程池原理

1.使用线程池的意义何在&#xff1f;项目开发中&#xff0c;为了统一管理线程&#xff0c;并有效精准地进行排错&#xff0c;我们经常要求项目人员统一使用线程池去创建线程。因为我们是在受不了有些人动不动就去创建一个线程&#xff0c;使用的多了以后&#xff0c;一旦报错就…

Android从屏幕刷新到View的绘制(一)之 Window、WindowManager和WindowManagerService之间的关系

0. 相关分享 Android从屏幕刷新到View的绘制&#xff08;一&#xff09;之 Window、WindowManager和WindowManagerService之间的关系 Android从屏幕刷新到View的绘制&#xff08;二&#xff09;之Choreographer、Vsync与屏幕刷新 1. 相关类 WindowManagerService&#xff0c…

Linux安装Redis步骤

1 下载安装包并解压 官网&#xff1a;https://download.redis.io 下载安装包&#xff1a; wget https://download.redis.io/redis-stable.tar.gz 解压 tar -zxvf redis-stable.tar.gz* 2 安装 安装 cd redis-stable make install PREFIX/opt/install/redis6 设置环境变量 vi …

Python学习-----项目设计1.0(设计思维和ATM环境搭建)

目录 前言&#xff1a; 项目开发流程 MVC设计模式 什么是MVC设计模式&#xff1f; ATM项目要求 ATM项目的环境搭建 前言&#xff1a; 我个人学习Python大概也有一个月了&#xff0c;在这一个月中我发布了许多关于Python的文章&#xff0c;建立了一个Python学习起步的专栏…

企业级信息系统开发学习1.3——利用注解配置取代Spring配置文件

文章目录一、利用注解配置类取代Spring配置文件&#xff08;一&#xff09;打开项目&#xff08;二&#xff09;创建新包&#xff08;三&#xff09;拷贝类与接口&#xff08;四&#xff09;创建注解配置类&#xff08;五&#xff09;创建测试类&#xff08;六&#xff09;运行…

史上最经典垃圾回收器(CMS,G1)详解、适用场景及特点、使用命令

文章目录垃圾收集器介绍总结各个垃圾收集器之间的关系垃圾收集器使用命令及默认值详解各个垃圾收集器SerialParNewParallel ScavengeSerial OldParallel OldCMS(Concurrent Mark Sweep)G1(Garbage First)适用场景及推荐垃圾收集器介绍总结 垃圾收集器可以帮助我们进行具体的垃…

HDFS优化

单节点多块磁盘数据均衡 生成HDFS块均衡计划 hdfs diskbalancer -plan node1 执行均衡计划,node1.plan.json均衡计划文件 hdfs diskbalancer -execute node1.plan.json 查看当前均衡任务的执行情况 hdfs diskbalancer -query node1 取消均衡任务hdfs diskbalancer -cancel nod…

(三十九)undo log版本链是个什么东西?

今天我们正式开始切入讲解MySQL中多个事务并发执行时的隔离到底是怎么做的&#xff0c;因为我们知道默认是骚气的RR隔离级别&#xff0c;也就是说脏写、脏读、不可重复读、幻读&#xff0c;都不会发生&#xff0c;每个事务执行的时候&#xff0c;跟别的事务压根儿就没关系&…

移动web基础

初始缩小&#xff1a;布局视口大于视觉视口 初始放大&#xff1a;布局视口小于视觉视口 布局视口等于视觉视口&#xff08;这种动作行为叫做理想视口&#xff09; <meta name"viewport" content"width375" /> <meta name"viewport"…

云原生|kubernetes|网络插件flannel二进制部署和calico的yaml清单部署总结版

前言&#xff1a; 前面写了一些关于calico的文章&#xff0c;但感觉好像是浅尝辄止&#xff0c;分散在了几篇文章内&#xff0c;并且很多地方还是没有说的太清楚云原生|kubernetes|kubernetes的网络插件calico和flannel安装以及切换_calico换flannel_晚风_END的博客-CSDN博客 …

在C#中使用信号量解决多线程访问共享资源的冲突问题

目前在我写的233篇原创文章中&#xff0c;有两篇是粉丝可见的&#xff0c;其中《C#线程的参数传递、获取线程返回值以及处理多线程冲突》这篇文章有179个粉丝关注&#xff0c;看到不断有人关注这篇文章&#xff0c;这表明学习C#的人还是挺多的&#xff0c;感觉文章内容不够厚实…

泛型<E>

泛型 案例引出泛型 按要求写出代码&#xff1a; 在ArrayList中添加3个Dog对象&#xff0c;Dog对象有name和age两个属性&#xff0c;且输出name和age public class test1 {public static void main(String[] args) {ArrayList list new ArrayList();list.add(new Dog(10,&quo…

Python解题 - CSDN周赛第32期 - 运输石油(三维背包)

上期周赛因为最后一题出现bug&#xff0c;再加上都是经典的模板题&#xff0c;问哥就懒得写题解了。 本期也是有两道考过的题目&#xff0c;不过最后一题因为考到了背包问题的特殊类型&#xff0c;还是值得拿出来记个笔记。 第一题&#xff1a;传奇霸业 传奇霸业&#xff0c;是…

Unity高程图生成

序大概就是根据一个灰度图&#xff0c;生成一个地形。分两步来实现吧&#xff1b;首先&#xff0c;用随机数生成地形&#xff1b;然后&#xff0c;根据灰度图生成地形。小白&#xff0c;没啥基础&#xff0c;所以只能慢慢来。参考&#xff1a;【萌新图形学】地形网格生成入门 含…

基于stm32电梯管理系统设计

基于stm32电梯管理系统设计这里记录一下以前自己做的嵌入式课程设计&#xff0c;报告中的图片和文字太多了&#xff0c;全部一个一个把搬过来太麻烦了,需要完整文本和代码自行q我963160156&#xff0c;也可在微信公众号 *高级嵌入式软件* 里回复 *电梯* 查看完整版文章摘要关键…

Oracle Apex 21.2 安装过程

什么是 Oracle APEX&#xff1f; Oracle APEX 是广受欢迎的企业级低代码应用平台。借助该平台&#xff0c;您可以构建功能先进的可扩展安全企业应用&#xff0c;并在任何位置&#xff08;云或内部部署&#xff09;部署这些应用。 使用 APEX&#xff0c;开发人员可快速开发并部…

域组策略自动更新实验报告

域组策略自动更新实验报告 域组策略自动更新实验报告 作者: 高兴源 1要求、我公司为了完善员工的安全性和系统正常漏洞的维护&#xff0c;所以采用域组策略自动更新的方法来提高账户安全性&#xff0c;减少了用户的错误。 1.实验环境如下1台2008r2一台创建域&#xff0c;一台wi…