total number of document in asp.net core - c#

I have a document table here is my query how can I sum the documents that I now have in sql and display in viewmodel by linq in asp.net core 3.1
public async Task<PagedResult<DocumentsVm>> GetTotal(GetDocumentsPagingRequest request)
{
var query = from d in _context.Documents //This is my query
join u in _context.Users on d.UserID equals u.Id
select new { d, u };
int TotalRow = await query.CountAsync();
var data = await query.Skip((request.PageIndex - 1) * request.PageSize)
.Take(request.PageSize)
.Select(x => new DocumentsVm()
{
ID = x.d.ID,
Caption = x.d.Caption,
FacultyID = x.d.FacultyOfDocumentID,
Status = x.d.Status,
CreateOn = x.d.CreateOn.Date,
ViewCount = ??? //I want to display total document here
}).ToListAsync();
var pagedResult = new PagedResult<DocumentsVm>()
{
TotalRecord = TotalRow,
Items = data
};
return pagedResult;
}

Related

Search query with parameters in linq c#

I need to build a search query with dynamic parameters in net core 3.0.
IQueryable<UserDto> query =
from user in dbContext.DB_USER
join items in dbContext.DB__ITEMS on user.IdItem equals items.IdItem
join cars in dbContext.DB_CARS on user.IdCars equals cars.IdItem
join statsCar in dbContext.DB_STATS_CARS on cars.IdCars equals statsCar.Id
select new UserDto
{
Id = user.Id,
Name = user.Name,
Data = user.Data.HasValue ? user.Data.Value.ToUnixTime() : default(long?),
Lvl = user.L,
Items = new ItemsUdo
{
Id = items.Id,
Type = items.Type,
Value = items.Value
},
Cars = new CarsDto
{
Id = cars.Id,
Model = cars.model,
Color = cars.Color
}
};
I would like to add search parameters like user name, items type, cars model and data from user. I tried to add "where" before 'select new UserDto' but not always user will provide all search parameters. If I give below:
if(fromSearch.UserName != null && fromSearch.UserName.Lenght > 0)
{
query = query.Where(u => u.Name == fromSearch.UserName);
}
it works(on user.data does not work) but is it correct? How to do this in linq query?
Do something like this:
IQueryable<UserDto> query =
from user in dbContext.DB_USER
join items in dbContext.DB__ITEMS on user.IdItem equals items.IdItem
join cars in dbContext.DB_CARS on user.IdCars equals cars.IdItem
join statsCar in dbContext.DB_STATS_CARS on cars.IdCars equals statsCar.Id;
select new UserDto
{
Id = user.Id,
Name = user.Name,
Data = user.Data.HasValue ? user.Data.Value.ToUnixTime() : default(long?),
Lvl = user.L,
Items = new ItemsUdo
{
Id = items.Id,
Type = items.Type,
Value = items.Value
},
Cars = new CarsDto
{
Id = cars.Id,
Model = cars.model,
Color = cars.Color
}
};
if(!string.IsNullOrWhitespace(username))
query = query.Where(ud => ud.Name == username);
if(!string.IsNullOrWhitespace(itemtype))
query = query.Where(ud => ud.Items.Any(i => i.Type == itemtype));
if(!string.IsNullOrWhitespace(carmodel))
query = query.Where(ud => ud.Cars.Any(c => c.Model == carmodel));
etc. These will work like AND; if you specify a username and an itemtype you get only those users named that, with that item type somewhere in the items list.. etc

Return children and subchildren withouth having sub-array Linq

I have a linq query that returns users/employees with their corresponding supervisors.
List<OrgChartViewModel> OrgChart = new List<OrgChartViewModel>();
var userlist = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist);
return Json(OrgChart.DistinctBy(x => x.id));
However, I need a query that returns the supervisor and their children along with their sub-children without having a sub-array/nested array.
What I have tried :
List<OrgChartViewModel> OrgChart = new List<OrgChartViewModel>();
var userlist = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist);
foreach (var ul in userlist)
{
var userlist2 = (from u in users
select new OrgChartViewModel
{
id = u?.id.ToString(),
pid = u?.pid.ToString(),
name = u?.name,
title = u?.title,
img = u?.img
}).Where(x => x.pid == ul.id).OrderBy(x => x.name).ToList();
OrgChart.AddRange(userlist2);
}
return Json(OrgChart.DistinctBy(x => x.id));
But this only returns the first layer of sub-children. What I want to achieve is to return unlimited layers of sub-children without having sub-arrays.

How to apply multiple optional filters in a LINQ query

I have a page where user can select any number of search filters to apply search
When user clicks on search, these parameters are passed to my GetIndicatorData method to perform the query. However, it doesn't seem to work for me.
Here is my code
public static List<tblindicators_data_custom> GetIndicatorsData(string status, int service_id, int operator_id, string year, string frequency)
{
var date = Convert.ToDateTime(year + "-01-01");
int[] numbers = status.Split(',').Select(n => int.Parse(n)).ToArray();
var ict = new ICT_indicatorsEntities();
var result = from ind in ict.tblindicators_data
join ser in ict.tblservices on ind.service_id equals ser.Id
join oper in ict.tbloperators on ind.operator_id equals oper.Id
where numbers.Contains(ind.status) && (ind.date_added.Year == date.Year)
select new
{
ind.Id,
ind.service_id,
ind.survey_id,
ind.operator_id,
ind.type,
ind.date_added,
ind.quater_start,
ind.quater_end,
ind.status,
ind.month,
service = ser.name,
operator_name = oper.name
};
List<tblindicators_data_custom> data = new List<tblindicators_data_custom>();
foreach (var item in result)
{
tblindicators_data_custom row = new tblindicators_data_custom();
row.Id = item.Id;
row.survey_id = item.survey_id;
row.service_id = item.service_id;
row.service_name = item.service;
row.operator_id = item.operator_id;
row.operator_name = item.operator_name;
row.date_added = item.date_added;
row.quater_start = item.quater_start;
row.type = item.type;
row.quater_end = item.quater_end;
row.month = item.month == null? DateTime.Now:item.month;
row.status = item.status;
data.Add(row);
}
return data;
}

Error when executing asynchronous pagination call

I have a ASP .Net Core MVC app where I have a table in a view that is being populated by data from an entity framework query. Following this guide, I've implemented code to paginate the table. For some reason, when the request for the table data is sent from the client side to controller action, there is the following error:
InvalidOperationException: The provider for the source IQueryable doesn't implement IAsyncQueryProvider. Only providers that implement IEntityQueryProvider can be used for Entity Framework asynchronous operations.
Here is the controller action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GetResultList(ResortDataJoinObj resDeals, int page =1)
{
if (ModelState.IsValid)
{
var resultsObj = (from rd in _db.ResortData
join ra in _db.ResortAvailability on rd.RecNo equals ra.RecNoDate
where ra.TotalPrice < Int32.Parse(resDeals.priceHighEnd) && ra.TotalPrice > Int32.Parse(resDeals.priceLowEnd)
select new
{
Name = rd.Name,
ImageUrl = rd.ImageUrl,
ResortDetails = rd.ResortDetails,
CheckIn = ra.CheckIn,
Address = rd.Address,
TotalPrice = ra.TotalPrice
});
int i = 0;
List<ResortDealResultsObject> resultList = new List<ResortDealResultsObject>();
foreach (var row in resultsObj)
{
var tempVm = new ResortDealResultsObject
{
Name = row.Name,
ImageUrl = row.ImageUrl,
ResortDetails = row.ResortDetails,
CheckIn = row.CheckIn,
Address = row.Address,
TotalPrice = row.TotalPrice
};
resultList.Add(tempVm);
}
int pageSize = 3;
var model = await PaginatedList<ResortDealResultsObject>.CreateAsync(resultList.AsQueryable(), page, pageSize);
ResortDataJoinObj joinObj = new ResortDataJoinObj();
joinObj.PageList = model;
ViewBag.rowsReturned = true;
return View(joinObj);
}
return View(resDeals);
}
It looks like the error is being caused by the line var model = await PaginatedList<ResortDealResultsObject>.CreateAsync(resultList.AsQueryable(), page, pageSize);
This line is calling a method within the class PaginatedList, which is implemented in its own file (as outlined in the guide):
public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize)
{
var count = await source.CountAsync();
var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync();
return new PaginatedList<T>(items, count, pageIndex, pageSize);
}
There are no pre-compiler or compilation errors so I'm not sure exactly what is wrong here since I'm following the guide pretty closely. What could be causing the error?
List<ResortDealResultsObject> resultList = new List<ResortDealResultsObject>();
foreach (var row in resultsObj)
{
var tempVm = new ResortDealResultsObject
{
Name = row.Name,
ImageUrl = row.ImageUrl,
ResortDetails = row.ResortDetails,
CheckIn = row.CheckIn,
Address = row.Address,
TotalPrice = row.TotalPrice
};
resultList.Add(tempVm);
}
This code is not generated by entity framework and does not provide asynchronious calls.
You already have a List when you call the ToListAsync() method so there is no point to cast it to a Queryable and call ToListAsync() on it
The following code should do the work
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> GetResultList(ResortDataJoinObj resDeals, int page =1)
{
if (ModelState.IsValid)
{
var resultsObj = from rd in _db.ResortData
join ra in _db.ResortAvailability on rd.RecNo equals ra.RecNoDate
where ra.TotalPrice < Int32.Parse(resDeals.priceHighEnd) && ra.TotalPrice > Int32.Parse(resDeals.priceLowEnd)
select new ResortDealResultsObject
{
Name = rd.Name,
ImageUrl = rd.ImageUrl,
ResortDetails = rd.ResortDetails,
CheckIn = rd.CheckIn,
Address = rd.Address,
TotalPrice = rd.TotalPrice
};
int pageSize = 3;
var model = await PaginatedList<ResortDealResultsObject>.CreateAsync(resultsObj, page, pageSize);
ResortDataJoinObj joinObj = new ResortDataJoinObj();
joinObj.PageList = model;
ViewBag.rowsReturned = true;
return View(joinObj);
}
return View(resDeals);
}
I didn't test it so there could be some compile time errors but the logic is there :)

Select List of Object Which Contain Another List by LINQ

I have three database model which are shown below
I have two DTO class which are shown below
class RoleDTO
{
string RoleId;
string EnglishName;
Guid TypeId;
List<ClaimDTO> claims;
}
class ClaimDTO
{
string ActionID;
string ActionCode;
string ActionLevel;
string GrantDate;
}
Now I want to retrieve List of RoleDTO object from the database. So far I tried
public List<RoleDTO> GetRoleByType(Guid roleTypeId)
{
var roleDTOs = (from r in ctx.Roles
join rc in ctx.RoleClaims on r.RoleID equals rc.RoleID
join a in ctx.Actions on rc.ActionID equals a.ActionID
where r.RoleTypeID == roleTypeId
select new RoleDTO
{
RoleId = r.RoleID,
EnglishName = r.EnglishName,
TypeId = r.TypeID,
claims = List of ClaimDTO objects related to this role
}).ToList();
return roleDTOs;
}
My question is how can I retrieve list of ClaimDTO objects inside select statement. Is my linq correct?
I am using Telerik OpenAccess as ORM.
Below change should help to get the results
public List<RoleDTO> GetRoleByType(Guid roleTypeId)
{
var roleDTOs = (from r in ctx.Roles
join rc in ctx.RoleClaims on r.RoleID equals rc.RoleID
where r.RoleTypeID == roleTypeId
select new RoleDTO
{
RoleId = r.RoleID,
EnglishName = r.EnglishName,
TypeId = r.TypeID,
claims = ctx.Actions.Where( c => c.ActionId == rc.ActionId).Select( s => new ClaimDTO
{
ActionID = s.ActionID,
ActionCode = s.ActionCode,
ActionLevel = s.ActionLevel,
GrantDate = s.GrantDate
})ToList()
}).ToList();
return roleDTOs;
}
Another Alternative
List<ClaimDTO> claimsList = ctx.Actions.Select( s => new ClaimDTO
{
ActionID = s.ActionID,
ActionCode = s.ActionCode,
ActionLevel = s.ActionLevel,
GrantDate = s.GrantDate
})ToList();
var roleDTOs = ctx.Roles.Join(ctx.RoleClaims, r => r.RoleID, rc => rc.RoleID, (r,rc) => new
{
r,rc
}).Where( r => r.RoleTypeID == roleTypeId)
.Select( row => new RoleDTO
{
RoleID = row.r.RoleID,
EnglishName = row.r.EnglishName,
TypeID = row.r.TypeID,
claims = claimsList.Where( c => c.ActionId == rc.ActionId)
}).ToList();
If you use Include method then below query could help
var roleDTOs = ctx.Roles.Include("RoleClaims").Join(ctx.Actions, r => r.RoleClaims.Select(rc => rc.ActionID).FirstOrDefault() , a => a.actionid , (r,a) => new
{
r,a
}.Where(r => r.RoleTypeID == roleTypeId)
.Select( row => new RoleDTO
{
RoleID = row.r.RoleID,
EnglishName = row.r.EnglishName,
TypeId = row.r.RoleTypeID,
Claims = row.a.Select( c => new ClaimDTO
{
ActionID = c.ActionID,
ActionCode = c.ActionCode,
ActionLevel = c.ActionLabel,
GrantDate = row.r.RoleClaims.Select( g => g.grantDate)
})
}).ToList();

Categories