I have the following select:
var sortedCodes = Codes
.Where(c => c.Active)
.OrderByDescending(x => x.SortOrder)
.Select(b => new { b.Display, b.NumericCode, b.SortOrder })
.Distinct()
.ToList();
The table Code has many columns such as NumericCode, TextCode, AlphaCode, ThreeCode, FourCode, FiveCode. I am using this table to build selects in my UI. Is there a way I can create some dynamic code so I can pass in the column name to use for the value?
The above select would look like this:
.Select(b => new { b.Display, "TextCode", b.SortOrder })
I was thinking I could use an Expression, but I do not think this is exactly what I need as it is actually printing the lambda as the value.
var arg = Expression.Parameter(typeof(Code), "b");
var body = Expression.Property(arg, valueColumn);
var lambda = Expression.Lambda<Func<Code, string>>(body, arg);
var sortedCodes = Codes
.Where(c => c.Active)
.OrderByDescending(x => x.SortOrder)
.Select(b => new { b.Display, Value=lambda, b.SortOrder })
.Distinct()
.ToList();
Related
I have view on which I use this request
Select Spendband, SUM(SpendCurrencyJob), SUM(SpendDocumentCount)
From analysis.vwJobSupplierMetrics
Where JobId = '500E0DD1-E3D3-4887-95EF-01D3C9EA8FD0'
Group by SpendBand
And it's running sucessfully
and get me this data
How I need to write it using linq to get same data?
I tried like this
var data = await _dbContext.VwJobSupplierMetrics.Where(x => x.JobId == jobId)
.GroupBy(x => x.SpendBand)
.Select(x => new HumpChartDto() {SpendBand = x.SpendBand}).ToListAsync();
But on new HumpChartDto() {SpendBand = x.SpendBand} I got Cannot resolve symbol 'SpendBand
How I can solve this?
First, after grouping on SpendBand, you need to access it via Key property. Second, to compute Sum, you can use Sum method.
var data = await _dbContext.VwJobSupplierMetrics.Where(x => x.JobId == jobId)
.GroupBy(x => x.SpendBand)
.Select(x => new HumpChartDto()
{
SpendBand = x.Key,
SumOfSpendCurrencyJob = x.Sum(s => s.SpendCurrencyJob),
SumOfSpendDocumentCount= x.Sum(s => s.SpendDocumentCount),
})
.ToListAsync();
Note - change the property name accordingly for name I've used for SumOfSpendCurrencyJob and SumOfSpendDocumentCount as don't know the definition of HumpChartDto class.
var entity = await _abcRepository.get(Id);
var X = entity.GroupBy(c => c.number).Where(grp => grp.Count() == 1).Take(10).ToList();
in images you see [0] and inside of it one more [0].
How can I get that model value.
X[0][0] is not working.
X.Value is not working.
I need to convert that dictionary to model.
Use .Select to normalize aggregation as per your wish.
var X = entity.GroupBy(c => c.number).Where(grp => grp.Count() == 1)
.Select(group => new { GroupKey = group.Key, Items = group.ToList() })
.Take(10).ToList();
You could try something like this:
var entity = await _abcRepository.get(Id);
var results = entity.GroupBy(c => c.number)
.Where(grp => grp.Count() == 1)
.Take(10)
.ToDictionary(grp => grp.Key, grp => grp.First());
Essentially, the lambda you pass in Where method certifies that the groups are created contains only one item. That being said, you can use the First on each group to fetch that one element.
I am seeing this "warning" in my logs. I am using EF Core 2.2.4
The LINQ expression 'GroupBy(new <>f__AnonymousType95`2(Date = [x].CreatedDate.Date, EmployeeId = [x].EmployeeId), [x])' could not be translated and will be evaluated locally
my query looks like this
var groupedEvents = dbContext.EventTrackings
.Where(x => // where clause )
.GroupBy(x => new { x.CreatedDate.Date, x.EmployeeId })
.OrderBy(x => x.Key.Date)
.ToList();
Try creating named property in your anonymous type .GroupBy(x => new { CreatedDate = x.CreatedDate.Date, x.EmployeeId }). I think it's not able to find and convert the Date property name to DB table column name if your actual db column name is CreatedDate.
var groupedEvents = dbContext.EventTrackings
.Where(x => // where clause )
.GroupBy(x => new { CreatedDate = x.CreatedDate.Date, x.EmployeeId })
.OrderBy(x => x.Key.CreatedDate)
.ToList();
I have this query witch is working fine :
List<IGrouping<Country, VisitedCity>> tempQuery = null;
using (var db = new MyDataContext())
{
tempQuery = db.VisitedCities.Include(c => c.PersonWhoVisited).Include(c => c.PersonWhoVisitedNationality).Include(c => c.City)
.GroupBy(c => c.PersonWhoVisitedNationality)
.ToList();
}
var dataInput = tempQuery
.OrderBy(c => c.Key.Name)
.Select(cp => new
{
CountryName = cp.Key.Name,
VisitationsByCity = cp
.GroupBy(x => x.City, x => x.CityId)
.Select(c => new
{
City = c.Key,
NumberOfVisits = c.Count()
})
}).ToList();
But the problem is that it is loading all data to my application (i have now 300 000 rows already on my largest table) and its getting slow day by day of course because its loading all in the ToList() method call.
I have this splitted in two calls because i cannot figure out how to make a single call to the database and return only the dataInput, if i merge both calls into one i get "Object reference not set to an instance of an object." exeption, this is probably because some references are not being included, but i cannot figure out what more tables i include in the query...
also im using entity framework 7 which still doesn't support lazy loading and has some features missing still, but this should be possible right?
In the includes i tried using a select statement
.Include(c => c.LadiesInWaiting.Select(b => b.Princess))
like mentioned on here : http://blogs.msdn.com/b/adonet/archive/2011/01/31/using-dbcontext-in-ef-feature-ctp5-part-6-loading-related-entities.aspx
but is not recognized (because its new entity framework 7 ?)
Update :
Ok if i use the .AsEnumerable i can make all in a single query, but still it seems to take for about 6 seconds to load the data in the next call and also loads 250 mb worth of memory at this instance of time ...
var tempQuery = db.VisitedCities.Include(c => c.PersonWhoVisitedNationality).Include(c => c.City)
.GroupBy(c => c.PersonWhoVisitedNationality)
.AsEnumerable()
.OrderBy(c => c.Key.Name)
.Select(cp => new
{
CountryName = cp.Key.Name,
VisitationsByCity = cp
.GroupBy(x => x.City, x => x.CityId)
.Select(c => new
{
City = c.Key,
NumberOfVisits = c.Count()
})
});
var allCities1 = tempQuery
.SelectMany(x => x.VisitationsByCity.Select(c => c.City))
.Distinct().OrderBy(city => city.Name).ToList();
Ok so i managed (of sort :P) to put all in a single query but i still have to call the .ToList() in order for the next data retrievals to work, if someone has a better solution please let me know .
var dataInput = db.VisitedCities
.GroupBy(c => c.PersonWhoVisitedNationalityId)
.Join(db.Countries, s => s.Key, c => c.CountryId, (s, c) => new { s, c })
.OrderBy(c => c.c.Name)
.Select(cp => new
{
Country = cp.c,
VisitationsByCity = cp.s
.GroupBy(x => x.CityId)
.Join(db.Cities, s => s.Key, c => c.CityId, (s, c) => new { s, c })
.Select(c => new
{
City = c.c,
NumberOfVisits = c.s.Count()
})
}).ToList();
This LINQ-to-SQL query works (testing in LINQpad):
var q5 = LOGs.Where(r => r.APP_NAME == "Toaster")
.GroupBy(pol => pol.CASE_NO)
.Select(grp => grp.First())
.OrderByDescending(l => l.WHEN);
q5.Dump();
However, that returns all columns for each row.
How can I refine the Select() part to specify certain columns?
I can do it in two steps by adding .ToList() to the query, then querying q5:
var q5a = q5.Select(r => new {CASE=r.CASE_NO, WHEN = r.WHEN});
q5a.Dump();
Can I accomplish that in one statement instead of two?
Thanks --
why don't you filter after where?
var q5 = LOGs.Where(r => r.APP_NAME == "Toaster")
.Select(r=> new{r.CASE_NO, r.WHEN})
.GroupBy(pol => pol.CASE_NO)
.Select(grp => grp.First())
.OrderByDescending(l => l.WHEN);
remembar that new {CASE=r.CASE_NO, WHEN = r.WHEN} creates a new anonymous type because of differents property names, new {r.CASE_NO, r.WHEN} doesn't !