Base solution for your next web application
Open Closed

Working with a generic repository filled be string tablename #9070


User avatar
0
geoteam created

Hello, I have an area in my program which repeats itself in different places again and again. I would like to implement this as a view component. A database table is always retrieved in this view component. This database table always has the structure ID, "name". Depending on the area where the view component is used, a different database table is required. The table name of the view component is therefore passed as a parameter. What is the best way to implement this in the existing abp structure, since you normally always work with a particular (named) repository using dependency injection. In my case I would need a "generic" repository, which is filled by the required database table (parameter table name). Even custom repositories always seem to depend on a specific entity. I hope this is understandable :-)


3 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @geoteam,

    You can follow two approaches.

    1. Define a cutom repository and access DbContext in it and query your view.
    2. Directly use IDbContextAccessor to access the DbContext and make the query.

    I suggest you to use option 1.

  • User Avatar
    0
    geoteam created

    Hello ismcagdas , can you please explain the first option a little more precisely? I have already worked with a custom repository (as described here https://aspnetboilerplate.com/Pages/Documents/Articles/Using-Stored-Procedures,-User-Defined-Functions-and-Views/index.html), but the problem exists here as well. The custom repository is always bound to a specific entity. In the example to User. Can I create a custom repository that is not bound to a specific entity?

    I want to modify this function so that the corresponding database table is queried using the input.tablename.

    public async Task<PagedResultDto<TitleDto>> GetTitlesForDatatable(GetTitlesInput input)
            {
                var tableName = input.TableName;
    
                //Decide based on TableName - do sql-statement 
                var query = _titleRepository.GetAll();
    
                var itemCount = await query.CountAsync();
    
                var titles = query
                    .OrderBy(input.Sorting)
                    .PageBy(input)
                    .ToList();
    
                var titleListDto = ObjectMapper.Map<List<TitleDto>>(titles);
    
                return new PagedResultDto<TitleDto>(
                    itemCount,
                    titleListDto
                    );
            }
    
  • User Avatar
    0
    musa.demir created

    Hello @geoteam

    It seems like using partial view will be easiest way to do that,

    Here is an example:

    public class MyController : AbpZeroTemplateControllerBase
    {
    	private readonly IRepository<Entity1> _entity1Repo;
    	private readonly IRepository<Entity2> _entity2Repo;
    
    	public AuditLogsController(IRepository<Entity1> entity1Repo, IRepository<Entity2> entity2Repo)
    	{
    		_entity1Repo = entity1Repo;
    		_entity2Repo = entity2Repo;
    	}
    
    	public ActionResult Page1()
    	{
    		var items = _entity1Repo.GetAll().Select(x=> new TitleDto(x.Id, x.Name)).ToList();
    		var model = new Page1ViewModel(){
    			partialViewItems = new PagedResultDto<TitleDto>(items.Count(),items)
    		};
    		return View(model);
    	}
    	
    	public ActionResult Page2()
    	{
    		var items = _entity2Repo.GetAll().Select(x=> new TitleDto(x.Id, x.DisplayName)).ToList();
    		var model = new Page2ViewModel(){
    			partialViewItems = new PagedResultDto<TitleDto>(items.Count(),items)
    		};
    		return View(model);
    	}
    }
    

    Than you can use that in you cshtml file

    @await Html.PartialAsync("~/Areas/AppAreaName/Views/Common/_TitlePartial.cshtml", model.partialViewItems)