Crud.EFCore.Template 7.0.5

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

// Install Crud.EFCore.Template as a Cake Tool
#tool nuget:?package=Crud.EFCore.Template&version=7.0.5

CRUDAPI and CrudCore NuGet package

Generic controller template implementing basic CRUD functions:

  • create entity from TCreateDto
  • read entities using List<TDto>
  • read entity with given id using TOneDto
  • update entity with given id from TCreateDto
  • delete entity with given id.

You will find this NuGet here.

User Manual

Requirements

Web API must have NuGet packages installed:

  • AutoMapper.Extensions.Microsoft.DependencyInjection,
  • Microsoft.EntityFrameworkCore

and configure:

  • AutoMapper e.g.
builder.Services.AddAutoMapper(Assembly.GetExecutingAssembly());
  • Application DbContext e.g.
    public static void AddAppDbContext(this IServiceCollection services, ConfigurationManager configuration)
    {
        services.AddDbContext<ApplicationDbContext>
                (options => options.UseNpgsql(configuration.GetConnectionString("DbConnection")));
        services.AddScoped<DbContextSeeder>();
    }

Using EntityControllerTemplate class

One-time configuration:
  1. Create the controller mapping loader in the API project:
using CrudCore.API.Mapping;

public class AppMappingProfile : MappingProfile
{
    public AppMappingProfile() : base(Assembly.GetExecutingAssembly()) { }
}
For any entity:
  1. Add an interface to the entity:
using CrudCore.Objects;

[DisplayName("klient")]
public class Client:IIdentifiable
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public virtual List<Order> Orders { get; set; }

}

(Optional) You could add name attribute to the entity ("klient").

  1. Create models for the entity:
public class ClientDto : CreateClientDto
{
    public int Id { get; set; }
}
public class ClientSimplyDto
{
    public int Id { get; set; }
    public string Name { get; set; }    
}
public class CreateClientDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
  1. Create the AutoMapper mapping class (which inherits from the SelfMapFrom generic class):
using CrudCore.API.Mapping;

public class ClientMapping : SelfMapFrom<Client>
{
    protected override void CreateMaps(Profile profile)
    {
        profile.CreateMap<Client, ClientDto>();

        profile.CreateMap<Client, ClientSimplyDto>()
               .ForMember(p => p.Name, x => x.MapFrom(c => $"{c.FirstName} {c.LastName}"));

        profile.CreateMap<ClientDto, Client>();

        profile.CreateMap<CreateClientDto, Client>();
    }
}
  1. Create the controller (which inherits from the EntityControllerTemplate generic class):
using CrudCore.API;
using Microsoft.AspNetCore.Mvc;

[Route("api/client")]
[Authorize(Roles = RoleNames.Admin)]
public class ClientController
    : EntityControllerTemplate<Client, ClientDto, ClientSimplyDto, CreateClientDto>
{
    public ClientController(ApplicationDbContext context, IMapper mapper)
        : base(context, mapper) { }
}

And that's all!

This is the result:

image

Customize controllers functions

You can use entity functions:

  • Creater to create new entity,
  • Reader to get list of entities,
  • Reader2 to get one entity with given id,
  • Updater to update entity with given id,
  • Deleter to delete entity with given id.

Those functions have two methods:

public EntityFunctionTemplate<TEntity> SetEntityAction(Action<TEntity> entityAction){}
public EntityFunctionTemplate<TEntity> SetQueryableFunction(Func<IQueryable<TEntity>, IQueryable<TEntity>> includeFunc){}

The SetEntityAction method validate the entity:

Creator.SetEntityAction(ValidateNewEntity);

private void ValidateNewEntity(Product entity)
    {
        var duplicate = _set.FirstOrDefault(
            p => p.Name.ToLower() == entity.Name.ToLower() && p.Quality == entity.Quality);

        if (duplicate != null)
        {
            throw new CustomException($"Produkt o nazwie ${entity.Name} istnieje już w bazie danych!");
        }

        duplicate = _set.FirstOrDefault(p => p.Code == entity.Code && p.Quality == entity.Quality);

        if (duplicate != null)
        {
            throw new CustomException($"Produkt o kodzie ${entity.Code} istnieje już w bazie danych!");
        }
    }

The SetQueryableFunction method manipulate the entitys set:

Reader.SetQueryableFunction((entities) => entities.Include(p => p.ProductAmounts));

The EntityControllerTemplate class has endpoints:

    [HttpPost]
    public virtual async Task<int> AddNew([FromBody] TCreateDto dto)
       => await Creator.AddEntity(dto);

    [HttpGet]
    public virtual async Task<List<TDto>> GetAll()
        => await Reader.GetDtos<TDto>();

    [HttpGet("{id}")]
    public virtual async Task<TOneDto> GetDtoById(int id)
        => await Reader2.GetDtoById<TOneDto>(id);

    [HttpPut("{id}")]
    public virtual async Task Update(int id, [FromBody] TCreateDto dto)
        => await Updater.UpdateEntity(id, dto);

    [HttpDelete("{id}")]
    public virtual async Task Remove(int id)
        => await Deleter.RemoveEntity(id);
  1. For hiding endpoint use:
    [NonAction]
    public override Task Remove(int id) => base.Remove(id);
  1. For authorization off use:
    [AllowAnonymous]
    public override Task<List<ProductDto>> GetAll() => base.GetAll();

Using EntityCRUD class

For make more customisation use the EntityCRUD class insted of the EntityControllerTemplate class. The EntityCRUD class isn't controller, but is the container includes basic CRUD functions.

Example:

[Controller]
[Route("api/order")]
public class OrderController : EntityCRUD<Order>
{
    public OrderController(ApplicationDbContext context, IMapper mapper) : base(context, mapper)
    {
        Reader2.SetQueryableFunction(entities => entities.Include(p => p.Products));
    }

    [HttpGet]
    public async Task GetAll()
        => await Reader.GetDtos<OrderDto>();

    [HttpGet("{id}")]
    public async Task GetById(int id)
        => await Reader2.GetDtoById<OrderDetailsDto>(id);

    [HttpPost]
    public async Task<int> AddNew([FromBody] CreateOrderDto dto)
        => await Creator.AddEntity(dto);
}
More information you can find in the CRUDAPI project in this solution.
If you have any questions write to me.

License

MIT license

Product Compatible and additional computed target framework versions.
.NET 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 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in 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
7.0.5 179 4/15/2023
7.0.4 159 4/13/2023
6.0.16 157 4/15/2023
1.0.0 193 4/11/2023