Common.EFCore 1.4.3

dotnet add package Common.EFCore --version 1.4.3
                    
NuGet\Install-Package Common.EFCore -Version 1.4.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Common.EFCore" Version="1.4.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Common.EFCore" Version="1.4.3" />
                    
Directory.Packages.props
<PackageReference Include="Common.EFCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Common.EFCore --version 1.4.3
                    
#r "nuget: Common.EFCore, 1.4.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Common.EFCore@1.4.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Common.EFCore&version=1.4.3
                    
Install as a Cake Addin
#tool nuget:?package=Common.EFCore&version=1.4.3
                    
Install as a Cake Tool

Common.EFCore

实体类配置

仅使用实体基类

Statrup的ConfigureServices方法添加

services.AddAutoGenerationId(); //增加自增ID

继承公共基类

IdentityBaseEntity、IdentityBaseEntity<TKey>
IdentityOperatorEntity、IdentityOperatorEntity<Tkey>
IdentityOperatorStatusEntity、  IdentityOperatorStatusEntity<TKey>

模型配置继承

EntityTypeConfigurationIdentity、EntityTypeConfigurationIdentity<T, TKey>
EntityTypeConfigurationIdentityOperator、EntityTypeConfigurationIdentityOperator<T,TKey>
EntityTypeConfigurationIdentityOperatorStatus、EntityTypeConfigurationIdentityOperatorStatus<T, TKey>

标准使用

配置用户实体

/// <summary>
/// 用户信息
/// </summary>
public class User : IdentityBaseEntity
{
    private User() { }

    public User(string account, string passWord, bool isValid) : this()
    {
        Account = account;
        Password = passWord;
        IsValid = isValid;
        UserName = account;
        CreateTime = DateTime.Now.ToUnspecifiedDateTime();
    }

    /// <summary>
    /// 账号
    /// </summary>
    public string Account { get; set; }

    /// <summary>
    /// 密码
    /// </summary>
    public string Password { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    public DateTime CreateTime { get; set; }

    /// <summary>
    /// 用户名
    /// </summary>
    public string UserName { get; set; }

    /// <summary>
    /// 是否有效
    /// </summary>
    public bool IsValid { get; set; }
}

创建上下文OpenDbContext,继承DbContext,也可以继承自BaseDbContext(会自动配置OnModelCreating)

public class OpenDbContext : DbContext
{
    public OpenDbContext(DbContextOptions<OpenDbContext> options)
        : base(options) { }

    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
        base.OnModelCreating(modelBuilder);
    }
}

下面演示注入pgsql数据库的EFCore(需要安装包Common.EFCore.PostgresSQL)

// default
var conn = builder.Configuration["Conn"];
builder.Services.AddEntityFramework<OpenDbContext>(config =>
       {
           config.ConnectionString = conn; // 连接字符串
           config.Schema = "azrng"; // 指定schema
       });

// 其他配置
var migrationsAssembly = typeof(Program).GetTypeInfo().Assembly.GetName().Name;
var conn = builder.Configuration["Conn"];
builder.Services.AddEntityFramework<OpenDbContext>(config =>
       {
           config.ConnectionString = conn; // 连接字符串
           config.Schema = "azrng"; // 指定schema
       }, x =>
       {
           x.MigrationsAssembly(migrationsAssembly); // 指定迁移项目
       }, options =>
       {
           //options.UsePgToCharFunctions();
       })
       .AddUnitOfWork<OpenDbContext>();

然后注入IBaseRepository<User>即可使用,比如

var content = Guid.NewGuid().ToString();
await _baseResp.AddAsync(new TestEntity(content), true); // 自带SaveChanges

也可以注入IUnitOfWork来进行保存,例如下面测试用例

[Fact]
public async Task SingleDbContextAdd()
{
    var connectionStr = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test;port=5432";
    var service = new ServiceCollection();
    service.AddLogging(loggerBuilder =>
    {
        loggerBuilder.AddConsole();
    });
    service.AddEntityFramework<TestDbContext>(options =>
    {
        options.ConnectionString = connectionStr;
        options.Schema = "public";
    });

    await using var serviceProvider = service.BuildServiceProvider();
    using var scope = serviceProvider.CreateScope();

    var testRep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity>>();
    var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
    var content = Guid.NewGuid().ToString();
    await testRep.AddAsync(new TestEntity(content));

    var flag = await unitOfWork.SaveChangesAsync();
    Assert.True(flag > 0);

    await testRep.DeleteAsync(t => t.Content == content);
}

操作例子

单个上下文使用Repository

[Fact]
public async Task SingleDbContext()
{
    var connectionStr = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test;port=5432";
    var service = new ServiceCollection();
    service.AddLogging(loggerBuilder =>
    {
        loggerBuilder.AddConsole();
    });
    service.AddEntityFramework<TestDbContext>(options =>
    {
        options.ConnectionString = connectionStr;
        options.Schema = "public";
    });
    await using var serviceProvider = service.BuildServiceProvider();
    using var scope = serviceProvider.CreateScope();

    var testRep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity>>();
    var content = Guid.NewGuid().ToString();
    await testRep.AddAsync(new TestEntity(content), true);

    var count = await testRep.CountAsync(t => true);
    Assert.True(count > 0);

    await testRep.DeleteAsync(t => t.Content == content);
}

单个上下文使用Repository和IUnitOfWork

[Fact]
public async Task SingleDbContextAdd()
{
    var connectionStr = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test;port=5432";
    var service = new ServiceCollection();
    service.AddLogging(loggerBuilder =>
    {
        loggerBuilder.AddConsole();
    });
    service.AddEntityFramework<TestDbContext>(options =>
    {
        options.ConnectionString = connectionStr;
        options.Schema = "public";
    });

    await using var serviceProvider = service.BuildServiceProvider();
    using var scope = serviceProvider.CreateScope();

    var testRep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity>>();
    var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
    var content = Guid.NewGuid().ToString();
    await testRep.AddAsync(new TestEntity(content));

    var flag = await unitOfWork.SaveChangesAsync();
    Assert.True(flag > 0);

    await testRep.DeleteAsync(t => t.Content == content);
}

多上下文使用Reposiroty

[Fact]
public async Task MultiDbContext()
{
    var connectionStr = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test;port=5432";
    var connection2Str = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test2;port=5432";
    var service = new ServiceCollection();
    service.AddLogging(loggerBuilder =>
    {
        loggerBuilder.AddConsole();
    });
    service.AddEntityFramework<TestDbContext>(options =>
    {
        options.ConnectionString = connectionStr;
        options.Schema = "public";
    });
    service.AddEntityFramework<TestDb2Context>(options =>
    {
        options.ConnectionString = connection2Str;
        options.Schema = "public";
    });
    await using var serviceProvider = service.BuildServiceProvider();
    using var scope = serviceProvider.CreateScope();

    {
        var testRep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity, TestDbContext>>();
        var content = Guid.NewGuid().ToString();
        await testRep.AddAsync(new TestEntity(content), true);

        var count = await testRep.CountAsync(t => true);
        Assert.True(count > 0);

        await testRep.DeleteAsync(t => t.Content == content);
    }

    {
        var testRep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity, TestDb2Context>>();
        var content = Guid.NewGuid().ToString();
        await testRep.AddAsync(new TestEntity(content), true);

        var count = await testRep.CountAsync(t => true);
        Assert.True(count > 0);

        await testRep.DeleteAsync(t => t.Content == content);
    }
}

多上下文使用Reposiroty+IUnitOfWork

[Fact]
public async Task MultiContextUseUnitOfWork()
{
    var connectionStr = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test;port=5432";
    var connection2Str = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test2;port=5432";
    var service = new ServiceCollection();
    service.AddLogging(loggerBuilder =>
    {
        loggerBuilder.AddConsole();
    });
    service.AddEntityFramework<TestDbContext>(options =>
           {
               options.ConnectionString = connectionStr;
               options.Schema = "public";
           })
           .AddUnitOfWork<TestDbContext>();

    service.AddEntityFramework<TestDb2Context>(options =>
           {
               options.ConnectionString = connection2Str;
               options.Schema = "public";
           })
           .AddUnitOfWork<TestDb2Context>();
    await using var serviceProvider = service.BuildServiceProvider();
    using var scope = serviceProvider.CreateScope();

    {
        var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork<TestDbContext>>();
        var testDb1Rep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity, TestDbContext>>();
        var content = Guid.NewGuid().ToString();
        await testDb1Rep.AddAsync(new TestEntity(content));
        var flag = await unitOfWork.SaveChangesAsync();
        Assert.True(flag > 0);

        var count = await testDb1Rep.CountAsync(t => true);
        Assert.True(count > 0);

        await testDb1Rep.DeleteAsync(t => t.Content == content);
    }

    {
        var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork<TestDb2Context>>();
        var testDb2Rep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity, TestDb2Context>>();
        var content = Guid.NewGuid().ToString();
        await testDb2Rep.AddAsync(new TestEntity(content));
        var flag = await unitOfWork.SaveChangesAsync();
        Assert.True(flag > 0);

        var count = await testDb2Rep.CountAsync(t => true);
        Assert.True(count > 0);

        await testDb2Rep.DeleteAsync(t => t.Content == content);
    }
}

事务操作

直接注入IUnitOfWork使用
[HttpGet]
public async Task<int> AddAsync()
{
    await using var tran = await _ofWork.GetDatabase().BeginTransactionAsync();
    try
    {
        var list = new List<User>
                   {
                       new User("admin1", "123456", true),
                       new User("admin2", "123456", true),
                       new User("admin3", "123456", true),
                       new User("admin4", "123456", true),
                       new User("admin5", "123456", true),
                       new User("admin6", "123456", true)
                   };

        await _userRep.AddAsync(list, true);

        var userAddress = new UserAddress { Name = "淘宝", UserId = list[0].Id, Address = "上海市" };
        await _userAddressRep.AddAsync(userAddress, true);

        await tran.CommitAsync();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, $"添加失败 {ex.GetExceptionAndStack()}");
        await tran.RollbackAsync();
    }

    return 1;
}
直接注入IUnitOfWork使用CommitTransactionAsync
[HttpGet]
public async Task<int> Add2Async()
{
    await _ofWork.CommitTransactionAsync(async () =>
    {
        var list = new List<User>
                   {
                       new User("admin1", "123456", true),
                       new User("admin2", "123456", true),
                       new User("admin3", "123456", true),
                       new User("admin4", "123456", true),
                       new User("admin5", "123456", true),
                       new User("admin6", "123456", true)
                   };

        await _userRep.AddAsync(list, true);

        var userAddress = new UserAddress { Name = "淘宝", UserId = list[0].Id, Address = "上海市" };
        await _userAddressRep.AddAsync(userAddress, true);
    });
    return 1;
}
使用unitOfWork的GetDatabase
[Fact]
public async Task SingleDbContextAdd()
{
    var connectionStr = "Host=localhost;Username=postgres;Password=123456;Database=pgsql_test;port=5432";
    var service = new ServiceCollection();
    service.AddLogging(loggerBuilder =>
    {
        loggerBuilder.AddConsole();
    });
    service.AddEntityFramework<TestDbContext>(options =>
    {
        options.ConnectionString = connectionStr;
        options.Schema = "public";
    });

    await using var serviceProvider = service.BuildServiceProvider();
    using var scope = serviceProvider.CreateScope();

    var testRep = scope.ServiceProvider.GetRequiredService<IBaseRepository<TestEntity>>();
    var unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();

    await using var tran = await unitOfWork.GetDatabase().BeginTransactionAsync();

    try
    {
        {
            var content = Guid.NewGuid().ToString();
            await testRep.AddAsync(new TestEntity(content));

            var flag = await unitOfWork.SaveChangesAsync();
            Assert.True(flag > 0);
        }

        {
            var content = Guid.NewGuid().ToString();
            await testRep.AddAsync(new TestEntity(content));

            var flag = await unitOfWork.SaveChangesAsync();
            Assert.True(flag > 0);
        }
        await tran.CommitAsync();
    }
    catch (Exception ex)
    {
        await tran.RollbackAsync();
        _testOutputHelper.WriteLine(ex.Message);
    }
}

版本更新记录

  • 1.4.3
    • 修复IsUnTimeZoneDateTime方法默认值问题
  • 1.4.2
    • 支持老的creater、modifyer、modify_time
  • 1.4.1
    • 更新GetListAsync方法响应
  • 1.4.0
    • 调整目录
  • 1.4.0-beta8
    • IBaseRepository支持指定DbContext
  • 1.4.0-beta7
    • 机器id使用随机数生成
  • 1.4.0-beta6
    • 暴漏GetDatabase方法
  • 1.4.0-beta5
    • 修改更新人
  • 1.4.0-beta4
    • 修复long类型时候,ID没有生成问题
  • 1.4.0-beta3
    • 增加更多对ToPageListAsync的扩展
  • 1.4.0-beta2
    • 移除针对netstandard2.1版本的支持
  • 1.4.0-beta1
    • 支持.Net9
  • 1.3.2
    • 修复IUnitOfWork<IEntity>在多上下文中保存失败的问题
  • 1.3.1
    • 移出调用工作单元的时候才添加IUnitOfWork,默认会添加一个IUnitOfWork
  • 1.3.0
    • 适配Common.Db.Core的0.1.0版本
    • 增加分页扩展ToPageListAsync
  • 1.3.0-beta4
    • 修改方法SetDelete为SetDeleted
    • 默认设置创建时间的时候使用无时区时间,防止pgsql出问题
  • 1.3.0-beta3
    • 迁移Common.EfCore的类到DBCore中
  • 1.3.0-beta2
    • 升级.Net8
  • 1.3.0-beta1
    • 模型类优化
    • 将pgsql中列的PropertyBuilderExtensions迁移到该程序集
    • 增加BaseRepository作为公共的操作,且方法为虚方法
    • 移除IBaseRepository中的同步方法
  • 1.2.1
    • 查询请求类优化

    • QueryableExtensions类更新

  • 1.2.0
    • GetPageRequest增加一个查询关键字
    • 将EFCoreExtension内容迁移到工作单元下
    • 工作单元类需要单独注入,如services.AddUnitOfWork<BaseDbContext>();
  • 1.2.0-beta2
    • 将创建时间修改时间等改为传入方案,用来应对pgsql的时间区分有时区无时区方案
  • 1.2.0-beta1
    • 升级支持.net7
  • 1.0.0-beta8
    • 增加表达式树扩展方法,替换nuget包System.Linq.Dynamic.Core
  • 1.0.0-beta7
    • 增加执行SQL扩展
    • 增加非追踪
  • 1.0.0-beta5
    • 更新注册的方法从AddEntityBase变更为AddIdHelper()
  • 1.0.0-beta4
    • 支持主键自定义类型
  • 1.1.0-beta3
    • 增加分页相关的类
    • 去除common包的依赖
  • 1.1.0-beta2
    • 更新因为Common包升级导致的问题
  • 1.1.0-beta1
    • 修改版本支持.net5、.net6、.netstandard2.1
    • 修改OrderBy排序方法
  • 1.0.6
    • 修改QueryableExtensions扩展,分页支持返回总条数,如果参数错误抛出异常
  • 1.0.5
    • 修改QueryableExtensions扩展
  • 1.0.4
    • 增加默认注入,支持单独使用该库的model类AddEntityBase
    • 主键ID修改类型为long类型
  • 1.0.3
    • 基本的base类封装
    • IBaseRepository接口编写
    • 工作单元封装
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (5)

Showing the top 5 NuGet packages that depend on Common.EFCore:

Package Downloads
Common.EFCore.PostgresSql

操作PostgresSql基础方法

Common.EFCore.InMemory

封装基本的EFCore操作内存数据库的方法

Common.EFCore.MySQL

封住简单操作MySQL的方法

Common.EFCore.SQLite

封装了一些SQLite相关的方法

Common.EFCore.SQLServer

基本的对sqlserver增删改查的封装

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.4.3 186 9/1/2025
1.4.2 248 8/26/2025
1.4.1 125 8/17/2025
1.4.0 176 8/13/2025
1.4.0-beta8 146 8/12/2025
1.4.0-beta7 119 8/9/2025
1.4.0-beta6 115 8/9/2025
1.4.0-beta5 122 7/29/2025
1.4.0-beta4 554 7/23/2025
1.4.0-beta3 246 5/6/2025
1.4.0-beta1 297 3/1/2025
1.3.2 205 8/12/2024
1.3.1 331 8/11/2024
1.3.0 130 7/27/2024
1.3.0-beta4 105 7/27/2024
1.3.0-beta3 212 3/23/2024
1.3.0-beta2 205 12/30/2023
1.3.0-beta1 238 8/22/2023
1.2.1 241 8/19/2023
1.2.0 396 5/14/2023
1.2.0-beta2 509 11/18/2022
1.2.0-beta1 341 11/11/2022
1.1.0-beta8 248 9/20/2022
1.1.0-beta7 462 6/19/2022
1.1.0-beta6 440 4/4/2022
1.1.0-beta5 262 4/4/2022
1.1.0-beta4 295 3/17/2022
1.1.0-beta3 465 1/15/2022
1.1.0-beta2 366 1/1/2022
1.1.0-beta1 372 12/22/2021
1.0.6 821 12/16/2021
1.0.6-beta1 303 12/22/2021
1.0.5 534 12/3/2021
1.0.4 426 12/3/2021
1.0.3 570 11/18/2021
1.0.2 920 9/20/2021
1.0.1 608 9/18/2021
1.0.0 582 9/7/2021
0.0.3 654 8/25/2021
0.0.2 460 8/18/2021
0.0.1 627 6/26/2021