I have a query that should return a sum of total hours reported for the current week.
This code below returns the Correct total of hours but not for a specific user in the database.
public int reportedWeekTime(int currentWeek, string username)
{
var totalTime = (from u in context.Users
from r in context.Reports
from w in context.Weeks
from d in context.Days
where u.Id == r.UserId && r.weekNr.Equals(currentWeek) && r.Id == w.ReportId && w.DayId == d.Id
select d.Hour).DefaultIfEmpty(0).Sum();
return totalTime;
}
The first method returns the number 24, wich is correct but as i said, not for a specific user.
I am trying to do this, but it gives me 0 in return. What am i doing wrong?
public int reportedWeekTime(int currentWeek, string username)
{
var totalTime = (from u in context.Users
from r in context.Reports
from w in context.Weeks
from d in context.Days
where u.Id == r.UserId && r.weekNr.Equals(currentWeek) && r.Id == w.ReportId && w.DayId == d.Id && u.Username.Contains(username)
select d.Hour).DefaultIfEmpty(0).Sum();
return totalTime;
}
Update - Troubleshooting approach, create a new anonymous class with the u.Username property, the string username, and the comparison. It will be easier to visualize what is going on
var users = (from u in context.Users
select new
{
UsernameDb = u.Username,
UsernameSearch = username,
Comparison = u.Username.Contains(username),
}).ToList();
Original
I would modify your query slightly:
Use join's instead of from's with where clauses
Remove the DefaultIfEmpty(0)
(1) Is more for readability, but I think (2) is the cause of your problem
var totalTime = (from u in context.Users
join r in context.Reports on u.Id equals r.UserId
join w in context.Weeks on r.Id equals w.ReportId
join d in context.Days on w.DayId equals d.Id
where r.weekNr.Equals(currentWeek) && u.Username.Contains(username)
select d.Hour).Sum();
I would also make sure that the following query returns result. If not, than that would be your problem
var users = from u in context.Users
where u.Username.Contains(username)
select u;
Related
I have a array called searchWords, that is a dynamic array that stores peoples search words. I need to add an option for AND search. So the search will only retrieve items if both variables in searchWords contains for resultList. Now it is searchWords.Any. Will searchWords.All make this works?
var resultList = from c in context.Category
join q in context.Question on c.CategoryId equals q.CategoryId
join qf in context.QuestionFilter on q.QuestionId equals qf.QuestionId
join a in context.Answer on q.QuestionId equals a.QuestionId into QuestAnsw
from a2 in QuestAnsw.DefaultIfEmpty()
orderby c.SortOrder
orderby q.SortOrder
where qf.FilterId == filterKeyAsInt
&& q.Published == true
&& c.Published == true
&& q.CustomerId == customerId
&& (searchWords.Any(w => a2.Text.Contains(w))
|| searchWords.Any(w => c.Text.Contains(w))
|| searchWords.Any(w => q.Text.Contains(w)))
select new { Category = c, Question = q };
You can put multiple clauses inside an All(), e.g.
&& (searchWords.All(w =>
a2.Text.Contains(w) &&
c.Text.Contains(w) &&
q.Text.Contains(w)))
...
You can do this if use searchWords.All, but i think searchWords.Any is more intuitive.
var resultList = from c in context.Category
join q in context.Question on c.CategoryId equals q.CategoryId
join qf in context.QuestionFilter on q.QuestionId equals qf.QuestionId
join a in context.Answer on q.QuestionId equals a.QuestionId into QuestAnsw
from a2 in QuestAnsw.DefaultIfEmpty()
orderby c.SortOrder
orderby q.SortOrder
where qf.FilterId == filterKeyAsInt
&& q.Published == true
&& c.Published == true
&& q.CustomerId == customerId
&& !
(
searchWords.All(w => !a2.Text.Contains(w))
&& searchWords.All(w => !c.Text.Contains(w))
&& searchWords.All(w => !q.Text.Contains(w))
)
select new { Category = c, Question = q };
I have the LINQ to SQL as below, which works fine.
var qry = (from h in dc.Timesheets
join s in dc.Users on h.UserID equals s.UserID
join ug in dc.UserGroups on s.UserGroupID equals ug.UserGroupID
where h.BookedOn >= _dateFrom.Value && h.BookedOn <= _dateTo.Value
group h by ug.UserGroupID into g
orderby g.Count() descending
select new
{
UserGroupingID = g.Key,
BookingsPerDay = g.Count() / days
}).ToList();
Now I want to add the name of the User Group, but somehow I struggle to get the LINQ right.
My limited knowledge tells me I should add the Description to the Group clause as follow, but it's a no-go:
I try:
var qry = (from h in dc.Timesheets
join s in dc.Users on h.UserID equals s.UserID
join ug in dc.UserGroups on s.UserGroupID equals ug.UserGroupID
where h.BookedOn >= _dateFrom.Value && h.BookedOn <= _dateTo.Value
group h, GroupDescription = ug.Description by ug.UserGroupID into g
orderby g.Count() descending
select new
{
UserGroupingID = g.Key,
Description = g.Key.GroupDescription
BookingsPerDay = g.Count() / days
}).ToList();
Error: Cannot convert lambda expression to type
'System.Collections.Generic.IEqualityComparer' because it is not
a delegate type
I think you might missing the new keyword here!!
var qry = (from h in dc.Timesheets
join s in dc.Users on h.UserID equals s.UserID
join ug in dc.UserGroups on s.UserGroupID equals ug.UserGroupID
where h.BookedOn >= _dateFrom.Value && h.BookedOn <= _dateTo.Value
group new {h, GroupDescription = ug.Description} by new {GroupDescription} into g
orderby g.Count() descending
select new
{
UserGroupingID = g.Key,
Description = g.Key.GroupDescription
BookingsPerDay = g.Count() / days
}).ToList();
Shouldn't it be an == for the GroupDescription? And aren't you missing a comma in the select new statement?
I would like to use Average function with Count in my Linq to EF query. So if I have to explain what I try to realize with my code part in t-sql for more clear understanding, You can take look below them,
select s.SalesPointId, count(*) as ipp
from ScoreItem si
inner join Score s on s.Id = si.ScoreId
where si.ResearchGroupType = 0 and si.IsValidForSalesPoint = 1
group by s.SalesPointId
select avg(ipp)
from (
select s.SalesPointId, count(*) as ipp
from ScoreItem si
inner join Score s on s.Id = si.ScoreId
where si.ResearchGroupType = 0 and si.IsValidForSalesPoint = 1
group by s.SalesPointId
)
As a consequence I have wrote below code in Linq query,
List<CvmNameAndValue> AnatolianSalesHeadshipIPPScore = (from si in db.ScoreItem
join s in db.Score on si.ScoreId equals s.Id
join sp in db.SalesPoint on s.SalesPointId equals sp.Id
where (si.ResearchGroupType == ResearchGroupType.ScoreCard && si.IsValidForSalesPoint && sp.CompanyId == ContextData.User.CompanyId && s.ProjectPeriodId == ProjectPeriodId && spIds.Contains(sp.Id))
group s by s.SalesPointId into g
select new CvmNameAndValue
{
Name = SystemSetting.Label_AnatolianSalesHeadshipIPPScore,
Value = g.Average(x => db.Score.Count()).ToString()
})
.ToList();
retVal.Data.DataGroup = AnatolianSalesHeadshipIPPScore.ToList();
return retVal;
But, Unfortunately they didn't return same result for me, so if you have any suggestion about my logic mistakes, please feel to free and share with me,
Finally I have solved my problem, so if you need such as thing, it can be solve your problem,
double AnatolianSalesHeadshipIPPScore = 0;
AnatolianSalesHeadshipIPPScore = (from si in db.ScoreItem
join s in db.Score on si.ScoreId equals s.Id
join sp in db.SalesPoint on s.SalesPointId equals sp.Id
where (si.ResearchGroupType == ResearchGroupType.ScoreCard && si.IsValidForSalesPoint && sp.CompanyId == ContextData.User.CompanyId && s.ProjectPeriodId == ProjectPeriodId)
group si by s.SalesPointId into g
select new
{
sid = g.Key,
count = g.Count()
}).Average(m => m.count);
I want to sum records using Group by from the all data inside "result view".
can anyone guide me for this.!
Here is My Code
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select g.OrderByDescending(t => t.DateCreated)).ToList();
foreach (var xCo in tData1)
{
//I am getting Data in xCo
}
Based on #Nayeem Mansoori solution you can try this.
var tData1 = (from i in _data.Transactions
join y in _data.DeviceInformations on i.DeviceInfoId equals y.DeviceInfoId
join u in _data.AccountDevices on y.DeviceInfoId equals u.DeviceInfoId
where y.Active == true && u.AccountId == 1000001 && u.Active == true
group i by i.DeviceInfoId into g
select new {Id = DeviceInfoId, sum = g.Sum(x=>x.DeviceInfoId)};
I have read a few items on this, including How to select only the records with the highest date in LINQ but I don't know how to apply it to my case which is slightly more complex.
I am trying to get all AdjusterProfileStatusItem but only select the most recent s.statusDate. Currently, the query just returns all dates for all records; whereas I just want the most recent date for all records.
(from u in db.Users
join a in db.Adjusters
on u.id equals a.userID
join s in db.AdminAdjusterStatus
on a.id equals s.adjusterID
where u.userType.ToLower() == "adjuster"
&& s.status.ToLower() == "approved"
&& s.statusDate.Max() // causes syntax error...
select new AdjusterProfileStatusItem
{
user = u,
adjuster = a
})
Edit:
I have also tried this which gives me a syntax error...
(from u in db.Users
join a in db.Adjusters
on u.id equals a.userID
join s in db.AdminAdjusterStatus
on a.id equals s.adjusterID
where u.userType.ToLower() == "adjuster"
&& s.status.ToLower() == "approved"
group new { u, a, s } by s.adjusterID into x
select new AdjusterProfileStatusItem
{
user = u, // u does not exist in context
adjuster = a, // a does not exist in context
status = x.Max(y => y.statusDate) // anonymous type does not contain definition for 'statusDate'
})
I'm not sure how you feel about Lambda expressions but I would probably do this:
db.Users
.Join(db.Adjusters,
u => u.Id,
a => a.UserId,
(u, a) => new
{
User = u,
Adjuster = a
})
.Join(db.AdminAdjusterStatus,
a => a.Adjuster.Id,
s => s.AdjusterId,
(a, s) => new
{
User = a.User,
Adjuster = a.Adjuster,
AdminAdjusterStatus = s
})
.Where(x => x.User.userType == "adjuster"
&& x.AdminAdjusterStatus.status == "approved"
&& x.AdminAdjusterStatus.statusDate == db.AdminAdjusterStatus
.Where(y => y.AdjusterId ==
x.AdminAdjusterStatus.AdjusterId)
.Max(z => z.statusDate))
.Select(a => new AdjusterProfileStatusItem
{
user = a.User
adjuster = a.Adjuster
})
**EDIT!!!**
(from u in db.Users
join a in db.Adjusters
on u.id equals a.userID
join s in db.AdminAdjusterStatus
on a.id equals s.adjusterID
where u.userType.ToLower() == "adjuster"
&& s.status.ToLower() == "approved"
&& s.statusDate == GetMaxStatusDate(db.AdminAdjusterStatus.ToList(), s.AdjusterID)
select new AdjusterProfileStatusItem
{
user = u,
adjuster = a
})
private DateTime GetMaxStatusDate(List<AdminAdjusterStatus> statuses, int adjusterId)
{
return (from a in statuses
where a.AdjusterId == adjusterId
group a by a.AdjusterId into values
select values.Max(x => x.statusDate)).FirstOrDefault();
}
OR
(from u in db.Users
join a in db.Adjusters
on u.id equals a.userID
join s in db.AdminAdjusterStatus
on a.id equals s.adjusterID
where u.userType.ToLower() == "adjuster"
&& s.status.ToLower() == "approved"
&& s.statusDate == db.AdminAdjusterStatus
.Where(x => x.AdjusterId == s.AdjusterId)
.Select(y => y.statusDate)
.Max();
select new AdjusterProfileStatusItem
{
user = u,
adjuster = a
})