I want to query the database and get a sport object containing all inner lists, but for some reason I'm missing, the select only goes 2 levels deep in lists, any deepers and the lists property have a value of null,
example of the structure
public class Sports
{
public int id { get; set; }
public string name { get; set; }
public List<League> leagues { get; set; }
}
public class League
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public List<Team> teams { get; set; }
}
public class Team
{
public int id { get; set; }
public string name { get; set; }
public string successrate { get; set; }
public List<Player> players { get; set; }
}
public class Player
{
public int id { get; set; }
public string name { get; set; }
public int age { get; set; }
}
I created property in MyAppContext file as this
public DbSet<Sports> sports { get; set; }
now when I call an item using select or linq or any other way I tried, the sport object is always 2 Dimensional, meaning it doesn't go deeper than two levels in nested lists! Example of result using var sport=db.Sports.First() the result is {"id":1,"name":"Football","leagues":null} or if I used select()
var sportQuery = db.sports.Select(
s=>new Sports(){
id=s.id,
leagues=s.leagues,
name=s.name
}).First();
I still don't get full information {"id":1,"name":"Football","leagues":[{"id":1,"name":"fc","description":"Some Leauge","teams":null},{"id":2,"name":"al","description":"League","teams":null}]}
why is that! and how to get full object like this
{"id":1,"name":"Football","leagues":[{"id":1,"name":"fc","description":"Some Leauge","teams":[{"id":1,"name":"real madrid","successrate":null,"players":[{"id":1,"name":"Cristiano Ronaldo","age":21},{"id":2,"name":"Iniesta","age":38}]},{"id":2,"name":"Barcelona","successrate":null,"players":[{"id":1,"name":"Cristiano Ronaldo","age":21},{"id":2,"name":"Iniesta","age":38}]}]},{"id":2,"name":"al","description":"League","teams":[{"id":1,"name":"real madrid","successrate":null,"players":[{"id":1,"name":"Cristiano Ronaldo","age":21},{"id":2,"name":"Iniesta","age":38}]},{"id":2,"name":"Barcelona","successrate":null,"players":[{"id":1,"name":"Cristiano Ronaldo","age":21},{"id":2,"name":"Iniesta","age":38}]}]}]}
I've been stuck for days, Please any help would be much appreciated
Try following :
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataBase db = new DataBase();
var sportQuery = db.sports.Select(s=> s.leagues.Select(l => l.teams.Select(t => t.players.Select(p => new {
playerid = p.id,
playerName = p.name,
playerAge = p.age,
teamId = t.id,
teamName = t.name,
teamSucessrate = t.successrate,
leagueId= l.id,
leagueName= l.name,
leagueDescription = l.description,
sportId = s.id,
sportName = s.name
}))
.SelectMany(p => p))
.SelectMany(t => t))
.SelectMany(l => l)
.ToList();
}
}
public class DataBase
{
public List<Sports> sports { get; set;}
}
public class Sports
{
public int id { get; set; }
public string name { get; set; }
public List<League> leagues { get; set; }
}
public class League
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public List<Team> teams { get; set; }
}
public class Team
{
public int id { get; set; }
public string name { get; set; }
public string successrate { get; set; }
public List<Player> players { get; set; }
}
public class Player
{
public int id { get; set; }
public string name { get; set; }
public int age { get; set; }
}
}
problem solved using Include() and thenInclude()
https://learn.microsoft.com/en-us/ef/core/querying/related-data
however, that doesn't explain why Select() only loads one list property deep, also it seems like i should be able to load object with select only or linq
Related
How can I select the List of ExtrasName and ExtrasId in the following query.
The query contains some mathematical operations aswell.
var query =
from a in _context.Cities
from b in a.CityExtras
where a.CityId == CityId && extraIds.Contains(b.ExtrasId)
group new { a, b } by new { a.PricePerSqM , a.Name, a.CityId , } into g
select new
{
City = g.Key.Name,
PricePerSqM = g.Key.PricePerSqM,
TotalPrice = g.Sum(x => x.b.Price) + g.Key.PricePerSqM * squareMeter
};
My Models are:
public class Extras
{
public int ExtrasId { get; set; }
[Required]
public string ExtrasName { get; set; }
public ICollection<CityExtras> CityExtras { get; set; }
}
public class City
{
public int CityId { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int PricePerSqM { get; set; }
public ICollection<CityExtras> CityExtras { get; set; }
}
public class CityExtras
{
public int CityId { get; set; }
public City City { get; set; }
public Extras Extras { get; set; }
public int ExtrasId { get; set; }
public int Price { get; set; }
}
I need ExtrasNames and ExtrasId in the query
As they stand, your models are not going to allow you to do this easily. You should add navigation properties to your models, then your Linq will be much cleaner (no need for the double select), and you will be able to navigate upwards to the Extra object and get the data you want.
I'm building a feature with a jquery datatable, the idea is to have a list of stores in the parent row, and then when expanding the parent to list all the licensed terminals in child rows that are linked to the store parent row by a StoreLicenseId column. The issue I am having is that I have a ViewModel with two models, one for the list of stores and one for the licensed terminals. I'm busy building the method into my controller, my problem is in the second part of the method where I new up "StoreLicenseDetails = sl.Select(tl => new TerminalListViewModel()", all the references to tl.terminalId and tl.Terminalname. I get this error "StoreListViewModel does not contain a definition for TerminalID and no accessible extension method". I can see why this is happening, so my question really is, how do I include this "second" TerminalListViewModel into my method to form part of the query ?
ViewModel
public partial class StoreListViewModel
{
public List<TerminalListViewModel> StoreLicenseDetails { get; set; } = null!;
public int Id { get; set; }
public Guid StoreLicenseId { get; set; }
[DisplayName("Store Name")]
public string StoreName { get; set; } = null!;
[DisplayName("App One Licenses")]
public int QtyAppOneLicenses { get; set; }
[DisplayName("App Two Licenses")]
public int QtyAppTwoLicenses { get; set; }
[DisplayName("Date Licensed")]
public DateTime DateLicensed { get; set; }
[DisplayName("Licensed Days")]
public int LicenseDays { get; set; }
[DisplayName("Is License Active")]
public bool LicenseIsActive { get; set; }
}
public partial class TerminalListViewModel
{
public int Id { get; set; }
public Guid StoreLicenseId { get; set; }
public Guid TerminalId { get; set; }
public string TerminalName { get; set; } = null!;
public string LicenseType { get; set; } = null!;
public int TerminalLicenseDays { get; set; }
public DateTime DateLicensed { get; set; }
public bool LicenseIsActive { get; set; }
public bool IsDecommissioned { get; set; }
public DateTime LastLicenseCheck { get; set; }
}
Controller Method
//sl = StoreList
//tl = TerminalList
public IEnumerable<StoreListViewModel> GetStoreList()
{
return GetStoreList().GroupBy(sl => new { sl.StoreLicenseId, sl.StoreName, sl.QtyAppOneLicenses,
sl.QtyAppTwoLicenses, sl.DateLicensed, sl.LicenseDays,
sl.LicenseIsActive })
.Select(sl => new StoreListViewModel()
{
StoreName = sl.Key.StoreName,
QtyAppOneLicenses = sl.Key.QtyAppOneLicenses,
QtyAppTwoLicenses = sl.Key.QtyAppTwoLicenses,
DateLicensed = sl.Key.DateLicensed,
LicenseDays = sl.Key.LicenseDays,
LicenseIsActive = sl.Key.LicenseIsActive,
StoreLicenseId = sl.FirstOrDefault().StoreLicenseId,
StoreLicenseDetails = sl.Select(tl => new TerminalListViewModel()
{
StoreLicenseId = tl.StoreLicenseId,
TerminalId = tl.TerminalId,
TerminalName = tl.TerminalName,
}).ToList()
}).ToList();
}
Based on the error,I suppose your GetStoreList() method returns List<OrderListViewModel> ,but your OrderListViewModel doesn't contains properties of TerminalListViewModel,So you got the error
GetStoreList() method should return List<SourceModel>( Source is the model which contains all the properties of StoreListViewModel and TerminalListViewModel)
For example,the link your provided:Multiple child rows in datatable, data from sql server in asp.net core
public class OrderList
{
//source of properties of OrderListViewModel(parent rows)
public int OrderId { get; set; }
public string Customer { get; set; }
public string OrderDate { get; set; }
//source of properties of OrderListDetailViewModel(child rows)
public int KimlikId { get; set; }
public string Product { get; set; }
public string Color { get; set; }
public int Qntty { get; set; }
}
public class OrderListViewModel
{
public int OrderId { get; set; }
public string Customer { get; set; }
public string OrderDate { get; set; }
public List<OrderListDetailViewModel> OrderListDetails { get; set; }
}
public class OrderListDetailViewModel
{
public int KimlikId { get; set; }
public string Product { get; set; }
public string Color { get; set; }
public int Qntty { get; set; }
}
Orderlist contains all columns OrderListViewModel and OrderListDetailViewModel needs.
When it comes to your case,you should
create 3 models (source,parentrow,childrows)
model for parentrows contains the properties
StoreLicenseId,StoreName, QtyAppOneLicenses,QtyAppTwoLicenses, DateLicensed, LicenseDays,LicenseIsActive
and model for childrows contains the other properties of source model
If you still have questions,please show the data you pulled form db,and I'll write a demo for you
I have the following POCO classes:
public class Employees
{
public int EmployeeId
{
get;
set;
}
public int EmpImageId
{
get;
set;
}
public string EmployeePhotoUrl
{
get;
set;
}
public string EmpAddress
{
get;
set;
}
}
public class Images
{
public int ImageId
{
get;
set;
}
public string ImageUrl
{
get;
set;
}
public string ImgCode
{
get;
set;
}
}
public class EmployeeDTO
{
public int EmployeeId
{
get;
set;
}
public int EmpImageId
{
get;
set;
}
public string EmployeePhotoUrl
{
get;
set;
}
public string EmpAddress
{
get;
set;
}
}
While getting the list of Employees present in the system, for each Employee, the photourl (EmployeePhotoUrl) is fetched from the Images table using the EmpImageId property.
// Get the list of Employees
var employees = await _dbContext.Employees
.Select(ef => new EmployeeDTO
{
EmployeeId= ef.EmployeeId,
EmployeePhotoUrl = images.FirstOrDefault(im => im.ImageId.Equals(ef.EmpImageId)).EmployeePhotoUrl,
EmpAddress = ef.EmpAddress
}).Skip((pageNo - 1) * 100).Take(pageSize).ToListAsync();
I want to leverage Automapper in this case. The issue I see here is the assignment of EmployeePhotoUrl, since this property is fetched from another entity: Images
Can anyone help me to know how to leverage Automapper in this case.
I have a class CategoryModel in c#, which is an element of a tree:
public class CategoryModel
{
public string Id { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public string ParentCategoryId { get; set; }
public ICollection<string> ChildCategoriesIds { get; set; } = new List<string>();
public ICollection<string> ProductsIds { get; set; } = new List<string>();
}
public class Product
{
public string Id { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
}
The ChildCategoriesIds contains Id class CategoryModel.
The ProductsIds contains Id class Product.
How proccesed data in new classes:
public class CategoryNew
{
public string Uid { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public bool? IsDeleted { get; set; }
public IEnumerable<UidName> ChildCategories { get; set; } = new List<UidName>();
public IEnumerable<UidName> Products { get; set; } = new List<UidName>();
}
public class UidName
{
public string Uid { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public bool? IsDeleted { get; set; }
}
You can specify own constructor for CategoryNew, which will take as an argument object of class CategoryModel, in which you will set all properties of CategoryNew based on values of properties of CategoryModel:
public CategoryNew(CategoryModel cm){
// set properties
}
Then your method would be:
public List<CategoryNew> ConverModelToNew(List<CategoryModel> lstCatModel){
List<CategoryNew> lstCatNew = new List<CategoryNew>();
foreach(var item in lstCatModel){
lstCatNew.Add(new CetagoryNew(item));
}
return lstCatNew;
}
Assuming you are trying to convert one set of object to another set of objects.
First of all, I believe categories shouldl inherit UidName so you will memory more efficiently by reducing duplicate objects.
public class CategoryNew: UidName
{
public IEnumerable<CategoryNew> ChildCategories { get; set; } = new List<CategoryNew>();
public IEnumerable<UidName> Products { get; set; } = new List<UidName>();
}
public class UidName
{
public string Uid { get; set; }
public string Name { get; set; }
public string NameEng { get; set; }
public bool? IsDeleted { get; set; }
}
// first run to create products
var newProducts = products.Select(p => new UidName {
Uid = p.Id,
Name = p.Name,
NameEnd = p.NameEng
}).ToArray();
// second run to create categories with products
var newCategories = categories.Select(c => new CategoryNew {
Uid = c.Id,
Name = c.Name,
NameEng = c.NameEng,
IsDeleted = (bool?)null, //TODO
Products = newProducts.Where(p => c.ProductIds.Contains(p.Uid))
.ToList()
}).ToArray();
// last run find sub categories
foreach(var category in newCategories) {
var oldCategory = categories.First(c => c.Id == category.Uid);
category.ChildCategories = newCategories.Where(c => oldCategory.ChildCategoriesIds.Contains(c.Uid))
.ToArray();
}
How do I find which clubs have the most players in query. So the query would contain all the clubs that have the most players. For example if first club has 3 players, second club has 5 players and third club also has 5 players then there would be second and third club in the query. And i need to return list of the clubs.
public List<Club> ClubWithMostPlayers()
{
using (var context = new dataContext())
{
var query = ?????
return query.ToList();
}
}
These are classes that i use
public class Player
{
public int PlayerId { get; set; }
public string name { get; set; }
public string surname { get; set; }
public int yearOfBirth { get; set; }
public virtual List<PlayerClub> playerClub { get; set; }
}
public class Club
{
public int ClubId { get; set; }
public string name { get; set; }
public string stadium { get; set; }
public int yearOfConstruction { get; set; }
public virtual List<PlayerClub> playerClub { get; set; }
}
public class PlayerClub
{
public int PlayerClubId { get; set; }
public int PlayerId { get; set; }
public int ClubId { get; set; }
public virtual Player player { get; set; }
public virtual Club club { get; set; }
public int from { get; set; }
public int to { get; set; }
public int appearances { get; set; }
}
I know how to do it in SQL, but not in LINQ
Thank you for help
How about dividing your query into two parts.
// get number of maximum number of players in one club
var count = context.Clubs.Select(c => c.playerClub.Count()).Max();
// get clubs with specific number of players
var query = context.Clubs
.Where(c => c.playerClub.Count() == count);