CC.CodeGenerator 2023.5.329

dotnet add package CC.CodeGenerator --version 2023.5.329
NuGet\Install-Package CC.CodeGenerator -Version 2023.5.329
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="CC.CodeGenerator" Version="2023.5.329" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add CC.CodeGenerator --version 2023.5.329
#r "nuget: CC.CodeGenerator, 2023.5.329"
#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.
// Install CC.CodeGenerator as a Cake Addin
#addin nuget:?package=CC.CodeGenerator&version=2023.5.329

// Install CC.CodeGenerator as a Cake Tool
#tool nuget:?package=CC.CodeGenerator&version=2023.5.329

CC.CodeGenerator

利用.Net的Source Generator功能,生成开发过程中哪些无聊的代码。

优势

  • 代码实时生成,无需额外操作,立即生效
  • 开发过程中生成的代码,执行性能比运行时反射更有效率

视频介绍

https://www.bilibili.com/video/BV1sL411y79i/?spm_id_from=333.999.0.0

使用方法

安装代码生成包以及支持包

Install-Package CC.CodeGenerator
Install-Package CC.NetCore

因为VS的原因,在添加包引用或者升级包版本后,建议重启VS。

Program.cs中添加全局引用

global using CC.CodeGenerator;
global CC.Core

功能介绍

EF功能增强

多表级联查询

以下三个单条方法功能和性能是等效的

/// <summary>
/// 级联查询(原始写法)
/// </summary>
public void SelectStandardOrigin()
{
    var context = new DemoContext();

    var personne = context.Personnel.Where(x => x.PersonnelId == new Guid("92c26f2e-1dda-4c0b-9279-a4a66560d4be"))
        .Select(x => new PersonnelDto()
        {
            PersonnelId = x.PersonnelId,
            CompanyId = x.CompanyId,
            Name = x.Name,
            Gender = x.Gender,
            Birthday = x.Birthday,
            IsJob = x.IsJob,

            CompanyDto = new CompanyDto()
            {
                CompanyId = x.Company.CompanyId,
                Title = x.Company.Title,
                Address = x.Company.Address,
            },

            AchievementsDtos = x.Achievements.Select(x => new AchievementsDto()
            {
                AchievementsId = x.AchievementsId,
                PersonnelId = x.PersonnelId,
                Year = x.Year,
                Level = x.Level,
            }).ToList(),
        }).FirstOrDefault();
}

/// <summary>
/// 级联查询(精简写法)
/// </summary>
public void SelectStandardSingle()
{
    var context = new DemoContext();

    var personne = context.Personnel.Where(x => x.PersonnelId == new Guid("92c26f2e-1dda-4c0b-9279-a4a66560d4be"))
            .Select(x => new PersonnelDto(x)
            {
                CompanyDto = x.Company.ToCompanyDto(),
                AchievementsDtos = x.Achievements.ToAchievementsDtos(),
            }).FirstOrDefault();
}

/// <summary>
/// 级联查询(极简写法)
/// </summary>
public void SelectEasySingle()
{
    var context = new DemoContext();

    var personne = PersonnelDto.LoadGen(context, new Guid("92c26f2e-1dda-4c0b-9279-a4a66560d4be"));
}

检索数据直接输出多表数据

/// <summary>
/// 级联查询多条
/// </summary>
public void SelectList()
{
    var context = new DemoContext();

    var personnes = context.Personnel
        .Where(x => x.IsJob == true && (x.Company.Address == "上海" || x.Company.Address == "北京"))
        .ToPersonnelDtos().ToList();
}

多表级联添加、修改、删除

/// <summary>
/// 级联操作
/// </summary>
public void CascadeSave()
{
    var context = new DemoContext();

    //模拟前端提交了新增或编辑的Dto
    var personnel = CreatePersonnelDto();
    personnel.SaveGen(context);
    var saveResult = context.SaveChanges();

    //模拟修改了Dto进行保存
    personnel.IsJob = false;
    personnel.CompanyDto.Title = "公司改名";//编辑禁用时不会保存到数据库
    personnel.CompanyDto.Address = "北京";
    personnel.AchievementsDtos.Remove(personnel.AchievementsDtos.First(x => x.Year == 2020));
    personnel.AchievementsDtos.Add(new AchievementsDto()
    {
        AchievementsId = Guid.NewGuid(),
        PersonnelId = personnel.PersonnelId,
        Year = 2022,
        Level = "S_CascadeSave",
    });
    personnel.SaveGen(context);
    var updateResult = context.SaveChanges();

    //模拟删除Dto
    personnel.DeleteGen(context);
    var deleteResult = context.SaveChanges();
}


private PersonnelDto CreatePersonnelDto()
{
    var personnelId = new Guid("10000101-db1e-40dc-8ef4-65e95ff5698f");
    var personnel = new PersonnelDto()
    {
        PersonnelId = personnelId,
        Name = "超人_CascadeSave",
        Gender = "男",
        IsJob = true,
        Birthday = DateTime.Now,

        CompanyDto = new CompanyDto()
        {
            CompanyId = new Guid("10000201-db1e-40dc-8ef4-65e95ff5698f"),
            Title = "超越建筑公司_CascadeSave",
            Address = "上海",
        },
        AchievementsDtos = new List<AchievementsDto>()
        {
            new AchievementsDto()
            {
                AchievementsId=new Guid("10000301-db1e-40dc-8ef4-65e95ff5698f"),
                PersonnelId=personnelId,
                Year=2020,
                Level="A_CascadeSave"
            },
                new AchievementsDto()
            {
                AchievementsId= new Guid("10000302-db1e-40dc-8ef4-65e95ff5698f"),
                PersonnelId=personnelId,
                Year=2021,
                Level="B_CascadeSave"
            }
        }
    };
    return personnel;
}

单表级联增删改查

/// <summary>
/// 单表增删改查
/// </summary>
[TestMethod]
public void SLRD()
{
    var dto = SaveGen();
    LoadGen(dto);
    ReLoadGen(dto);
    DeleteGen(dto);
}

/// <summary>
/// 构造CompanyDto对象,并保存
/// </summary>
/// <returns></returns>
private CompanyDto SaveGen()
{
    var context = new DemoContext();
    //保存
    var newDto = new CompanyDto()
    {
        CompanyId = Guid.NewGuid(),
        Title = "Tim",
        Address = DateTime.Now.ToString(),
    };
    newDto.SaveGen(context);
    var save = context.SaveChanges();
    return newDto;
}

/// <summary>
/// 使用主键从数据库载入CompanyDto对象
/// </summary>
/// <param name="dto"></param>
private void LoadGen(CompanyDto dto)
{
    var context = new DemoContext();
    var loadDto = CompanyDto.LoadGen(context, dto.CompanyId);

    var loadResultDto = CompanyDto.LoadResultGen(context, dto.CompanyId);

    var loadNullResultDto = CompanyDto.LoadResultGen(context, Guid.NewGuid());
}

/// <summary>
/// 从数据库中更新CompanyDto对象中的内容
/// </summary>
/// <param name="dto"></param>
private void ReLoadGen(CompanyDto dto)
{
    var context = new DemoContext();
    var reLoadDto = new CompanyDto() { CompanyId = dto.CompanyId };
    reLoadDto.ReLoadGen(context);
}

/// <summary>
/// 从数据库删除CompanyDto
/// </summary>
/// <param name="dto"></param>
private void DeleteGen(CompanyDto dto)
{
    var context = new DemoContext();
    dto.DeleteGen(context);
    var delete = context.SaveChanges();
    var loadDto = context.Company.FirstOrDefault(x => x.CompanyId == dto.CompanyId);
}

对象复制

/// <summary>
/// 赋值:Dto=>Dto
/// </summary>
[TestMethod]
public void CopyFormDto()
{
    var s = new CompanyDto()
    {
        CompanyId = Guid.NewGuid(),
        Title = "Tim",
        Address = DateTime.Now.ToString(),
    };

    var t = new CompanyDto();
    t.CopyFormDto(s);
}

/// <summary>
/// 赋值:Dto=>Entity
/// </summary>
[TestMethod]
public void CopyToEntity()
{
    var s = new CompanyDto()
    {
        CompanyId = Guid.NewGuid(),
        Title = "Tim",
        Address = DateTime.Now.ToString(),
    };

    var t = new Company();
    s.CopyTo(t);
}

/// <summary>
/// 创建新的CompanyDto
/// </summary>
[TestMethod]
public void NewCompanyDtoGen()
{
    var dto = CompanyDto.NewGen();
    var dtoResult = CompanyDto.NewResultGen();
}

Dto结构

[Dto(typeof(DemoContext), typeof(Company))]
public partial class CompanyDto {
    public CompanyDto() { }
    /// <summary>
    /// 企业
    /// </summary>
    [DtoKey]
    public Guid CompanyId { get; set; }
         
    /// <summary>
    /// 名称
    /// </summary>
    [DtoEditDisable]
    public string Title { get; set; }      

    /// <summary>
    /// 地址
    /// </summary> 
    public string Address { get; set; }
}

[Dto(typeof(DemoContext), typeof(Personnel))]
public partial class PersonnelDto
{
    /// <summary>
    /// 员工
    /// </summary>
    [DtoKey]
    public Guid PersonnelId { get; set; }

    /// <summary>
    /// 企业
    /// </summary>
    public Guid CompanyId { get; set; }

    /// <summary>
    /// 姓名 
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// 性别
    /// </summary>
    public string Gender { get; set; }

    /// <summary>
    /// 生日
    /// </summary>
    public DateTime? Birthday { get; set; }

    /// <summary>
    /// 是否在职
    /// </summary>
    public bool IsJob { get; set; }

    [DtoForeignKey("Company", "CompanyId", true)]
    public CompanyDto CompanyDto { get; set; }

    [DtoForeignKey("Achievements", "AchievementsId", true, true)]
    public List<AchievementsDto> AchievementsDtos { get; set; }
}

[Dto(typeof(DemoContext), typeof(Achievements))]
public partial class AchievementsDto
{
    [DtoKey]
    public Guid AchievementsId { get; set; }

    /// <summary>
    /// 员工
    /// </summary>
    public Guid PersonnelId { get; set; }

    public int? Year { get; set; }

    public string Level { get; set; }
}

EF实体结构

public partial class Company
{
    /// <summary>
    /// 企业
    /// </summary>
    [Key]
    public Guid CompanyId { get; set; }

    /// <summary>
    /// 名称
    /// </summary>
    [StringLength(50)]
    public string Title { get; set; }

    /// <summary>
    /// 地址
    /// </summary>
    [Required]
    [StringLength(200)]
    public string Address { get; set; }

    [InverseProperty("Company")]
    public virtual ICollection<Personnel> Personnel { get; } = new List<Personnel>();
}

public partial class Personnel
{
    /// <summary>
    /// 员工
    /// </summary>
    [Key]
    public Guid PersonnelId { get; set; }

    /// <summary>
    /// 企业
    /// </summary>
    public Guid CompanyId { get; set; }

    /// <summary>
    /// 姓名
    /// </summary>
    [Required]
    [StringLength(50)]
    public string Name { get; set; }

    /// <summary>
    /// 性别
    /// </summary>
    [StringLength(50)]
    public string Gender { get; set; }

    /// <summary>
    /// 生日
    /// </summary>
    [Column(TypeName = "date")]
    public DateTime? Birthday { get; set; }

    /// <summary>
    /// 是否在职
    /// </summary>
    public bool IsJob { get; set; }

    [InverseProperty("Personnel")]
    public virtual ICollection<Achievements> Achievements { get; } = new List<Achievements>();

    [ForeignKey("CompanyId")]
    [InverseProperty("Personnel")]
    public virtual Company Company { get; set; }
}

public partial class Achievements
{
    [Key]
    public Guid AchievementsId { get; set; }

    /// <summary>
    /// 员工
    /// </summary>
    public Guid PersonnelId { get; set; }

    public int? Year { get; set; }

    [StringLength(50)]
    public string Level { get; set; }

    [ForeignKey("PersonnelId")]
    [InverseProperty("Achievements")]
    public virtual Personnel Personnel { get; set; }
}

服务自动注册

服务类添加Service特性

[Service]
public class ServicesScoped
{
}

[Service(LifeCycle = ELifeCycle.Transient)]
public class ServicesTransient
{
}

Program类中增加代码

CC.CodeGenerator.AutoDI.AddServices(builder);
There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
2023.5.329 249 3/29/2023
2023.4.325 204 3/25/2023
2023.3.304 246 3/4/2023
1.9.1.725 490 7/25/2022
1.9.0.723 381 7/23/2022
1.8.4.721 395 7/21/2022
1.8.3.719 414 7/19/2022
1.8.2.716 468 7/16/2022
1.8.1.709 434 7/9/2022
1.8.0.709 414 7/9/2022
1.7.0.617 413 6/17/2022
1.6.1.616 420 6/16/2022
1.6.0.508 424 5/8/2022
1.5.3.505 385 5/6/2022
1.4.3 414 5/4/2022
1.3.0 418 3/19/2022
1.2.0 403 3/12/2022
1.1.3 446 3/9/2022
1.1.1 434 1/26/2022
1.1.0 431 1/23/2022
1.0.18 451 1/21/2022
1.0.17 390 1/21/2022
1.0.16 396 1/19/2022