Db2Code–part 2- architecture

What we will build you can see here :

Each class will have it is own CodeTemplates\EFCore  templates from which will generate the code.

Let’s start with ExampleModels : Here will be the class definitions . From the table defintion , the DB2Code will generate

1. A definition of a interface with table columns as properties

public interface I_Department_Table 
{
 long IDDepartment { get; set; }
 string Name { get; set; }
}

2. A class with relationships

public partial class Department
{
    [Key]
    public long IDDepartment { get; set; }

    [StringLength(50)]
    [Unicode(false)]
    public string Name { get; set; } = null!;

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

3. class without relationship

public class Department_Table : I_Department_Table
{
 public long IDDepartment { get; set; }
 public string Name { get; set; }
 }

4. Explicit operator to convert 2 to 3

public static explicit operator Department_Table?(Department obj) { 
if(obj == null)
return null;
//System.Diagnostics.Debugger.Break();
var ret= new Department_Table();
ret.CopyFrom(obj as I_Department_Table );
return ret;
}
public static explicit operator Department?(Department_Table obj) { 
if(obj == null)
return null;
//System.Diagnostics.Debugger.Break();
var ret= new Department();
ret.CopyFrom(obj as I_Department_Table) ;
return ret;
}

5. Public method CopyFrom( interface)


public void CopyFrom(I_Department_Table other)  {
 this.IDDepartment = other.IDDepartment;
 this.Name = other.Name;
}

5. Enum with name of the columns

public enum eDepartmentColumns {
None = 0
,IDDepartment 
,Name 
}

6. Metadata with name of the tables and the columns

public static MetaTable metaData = new("Department");
static Department_Table (){
 MetaColumn mc=null;
 mc=new ("IDDepartment","long",false);
 metaData.AddColumn(mc);
 mc=new ("Name","string",false);
 metaData.AddColumn(mc);
}

 

Now it comes ExampleContext . Here will the database context and various search definitions that you need (e.g. for a column of type int, search will generate  = , > , < , between , in array  ) . More , it will generate metadata for the tables that are part of the context.

public  IAsyncEnumerable&lt;Department&gt; DepartmentSimpleSearch(GeneratorFromDB.SearchCriteria sc, eDepartmentColumns colToSearch, string value){}
public  IAsyncEnumerable&lt;Department&gt; DepartmentGetAll(){}
public async Task&lt;Department[]&gt; DepartmentFind_Array( SearchDepartment? search){}
public Task&lt;long&gt; DepartmentCount( SearchDepartment search)

 

Now it comes ExampleControllers  . This will generate controllers for REST API for the table and also Search Controllers for any kind of search that you may want.

//this is the REST controller
[ApiController]
[Route("[controller]")]    
public partial class RESTDepartmentController : Controller
{
    private ApplicationDBContext _context;
    public RESTDepartmentController(ApplicationDBContext context)
	{
        _context=context;
	}
    [HttpGet]
    public async Task&lt;Department_Table[]&gt; Get(){
        var data= await _context.Department.ToArrayAsync();
        var ret = data.Select(it =&gt; (Department_Table)it!).ToArray();
        return ret;

        
    }
    
        [HttpGet("{id}")]
    public async Task&lt;ActionResult&lt;Department_Table&gt;&gt; GetDepartment(long id)
    {
        if (_context.Department == null)
        {
            return NotFound();
        }
        var item = await _context.Department.FirstOrDefaultAsync(e =&gt; e.IDDepartment==id);

        if (item == null)
        {
            return NotFound();
        }

        return (Department_Table)item!;
    }


    [HttpPatch("{id}")]
        public async Task&lt;IActionResult&gt; PutDepartment(long id, Department value)
        {
            if (id != value.IDDepartment)
            {
                return BadRequest();
            }

            _context.Entry(value).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!DepartmentExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return NoContent();
        }

        [HttpPost]
        public async Task&lt;ActionResult&lt;Department&gt;&gt; PostDepartment(Department_Table value)
        {
          
            var val = new Department();
            val.CopyFrom(value);
            _context.Department.Add(val);
            await _context.SaveChangesAsync();

            return CreatedAtAction("GetDepartment", new { id = val.IDDepartment }, val);
        }
        [HttpDelete("{id}")]
        public async Task&lt;IActionResult&gt; DeleteDepartment(long id)
        {
            if (_context.Department == null)
            {
                return NotFound();
            }
            var item = await _context.Department.FirstOrDefaultAsync(e =&gt; e.IDDepartment==id);
            if (item == null)
            {
                return NotFound();
            }

            _context.Department .Remove(item);
            await _context.SaveChangesAsync();

            return NoContent();
        }

        private bool DepartmentExists(long id)
        {
            return (_context.Department.Any(e =&gt; e.IDDepartment  == id));
        }

    }    

And also a SEARCH controller

[ApiController]
[Route("[controller]/[action]")]    
public partial class AdvancedSearchDepartmentController : Controller
{
    private ISearchDataDepartment _search;
    public AdvancedSearchDepartmentController(ISearchDataDepartment search)
	{
        _search=search;
	}

    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; GetAll()
    {
        await foreach(var item in _search.DepartmentFind_AsyncEnumerable(null))
        {
            yield return (Department_Table)item!;
        }
        
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; GetWithSearch(SearchDepartment s)
    {
        await foreach(var item in _search.DepartmentFind_AsyncEnumerable(s))
        {
            yield return (Department_Table)item!;
        }
        
    }

//has one key
    [HttpGet]
    public async Task&lt;Department_Table?&gt; GetSingle(long id){
        var data=await _search.DepartmentGetSingle(id);
       if(data == null)
        return null;
       return (Department_Table)data;
    }

                  [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; EqualValues_IDDepartment( long[]  values)
    {
        string? value=null;
        if(values.Length&gt;0)
            value=string.Join( ",",values);
        var sc=SearchDepartment.FromSearch(GeneratorFromDB.SearchCriteria.InArray,eDepartmentColumns.IDDepartment,value);
        await foreach (var item in _search.DepartmentFind_AsyncEnumerable(sc))
        {
        
            yield return (Department_Table)item!;
        }
    }
     [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; DifferentValues_IDDepartment( long[]  values)
    {
        string? value=null;
        if(values.Length&gt;0)
            value=string.Join( ",",values);
        var sc=SearchDepartment.FromSearch(GeneratorFromDB.SearchCriteria.NotInArray,eDepartmentColumns.IDDepartment,value);
        await foreach (var item in _search.DepartmentFind_AsyncEnumerable(sc))
        {
        
            yield return (Department_Table)item!;
        }
    }
         [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; EqualValue_IDDepartment( long  value)
    {
        var sc = GeneratorFromDB.SearchCriteria.Equal;
        await foreach (var item in _search.DepartmentSimpleSearch_IDDepartment(sc, value))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; DifferentValue_IDDepartment( long  value)
    {
        var sc = GeneratorFromDB.SearchCriteria.Different;
        await foreach (var item in _search.DepartmentSimpleSearch_IDDepartment(sc, value))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public  async IAsyncEnumerable&lt;Department_Table&gt; SimpleSearch_IDDepartment(GeneratorFromDB.SearchCriteria sc,  long value){
        await foreach(var item in _search.DepartmentSimpleSearch_IDDepartment(sc,value))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; FindNull_IDDepartment(){
        var sc = GeneratorFromDB.SearchCriteria.Equal;
        await foreach(var item in _search.DepartmentSimpleSearchNull_IDDepartment(sc))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; FindNotNull_IDDepartment(){
        var sc = GeneratorFromDB.SearchCriteria.Different;
        await foreach(var item in _search.DepartmentSimpleSearchNull_IDDepartment(sc))
        {
            yield return (Department_Table)item!;
        }
    }
              [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; EqualValues_Name( string[]  values)
    {
        string? value=null;
        if(values.Length&gt;0)
            value=string.Join( ",",values);
        var sc=SearchDepartment.FromSearch(GeneratorFromDB.SearchCriteria.InArray,eDepartmentColumns.Name,value);
        await foreach (var item in _search.DepartmentFind_AsyncEnumerable(sc))
        {
        
            yield return (Department_Table)item!;
        }
    }
     [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; DifferentValues_Name( string[]  values)
    {
        string? value=null;
        if(values.Length&gt;0)
            value=string.Join( ",",values);
        var sc=SearchDepartment.FromSearch(GeneratorFromDB.SearchCriteria.NotInArray,eDepartmentColumns.Name,value);
        await foreach (var item in _search.DepartmentFind_AsyncEnumerable(sc))
        {
        
            yield return (Department_Table)item!;
        }
    }
         [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; EqualValue_Name( string  value)
    {
        var sc = GeneratorFromDB.SearchCriteria.Equal;
        await foreach (var item in _search.DepartmentSimpleSearch_Name(sc, value))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; DifferentValue_Name( string  value)
    {
        var sc = GeneratorFromDB.SearchCriteria.Different;
        await foreach (var item in _search.DepartmentSimpleSearch_Name(sc, value))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public  async IAsyncEnumerable&lt;Department_Table&gt; SimpleSearch_Name(GeneratorFromDB.SearchCriteria sc,  string value){
        await foreach(var item in _search.DepartmentSimpleSearch_Name(sc,value))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; FindNull_Name(){
        var sc = GeneratorFromDB.SearchCriteria.Equal;
        await foreach(var item in _search.DepartmentSimpleSearchNull_Name(sc))
        {
            yield return (Department_Table)item!;
        }
    }
    [HttpGet]
    public async IAsyncEnumerable&lt;Department_Table&gt; FindNotNull_Name(){
        var sc = GeneratorFromDB.SearchCriteria.Different;
        await foreach(var item in _search.DepartmentSimpleSearchNull_Name(sc))
        {
            yield return (Department_Table)item!;
        }
    }
        


    


}//end class

 

Finally , ExampleWebAPI . This will add the controllers from the ExampleControllers   to show the use .

var assControllers = typeof(UtilsControllers).Assembly;
builder.Services.AddControllers()
              .PartManager.ApplicationParts.Add(new AssemblyPart(assControllers)); ;
        

 

Of course , the name Example will be replaced , from the template, with the name of your project