combine 2 queries from the same table into one linq query - c#

I have 2 queries that are query the same table but with different parameters and I would like to combine into one ,
Query 1
//ToDo refactor
int myDayOfWeek = 0;
DateTime dt = DateTime.Today;
myDayOfWeek = (int)dt.DayOfWeek;
var todaysLecture = (from c in _context.LectureGigs.Where(g => g.IsWeekLy == true && (int)g.Days == (myDayOfWeek))
select c).ToList();
//results Ok 1 result
Query 2
var upCommingLecture = _context.LectureGigs
.Include(g => g.Artist).Include(g => g.Genre)
.Where(g => g.DateTime > DateTime.Now && !g.IsCanceled);
//results Ok 2 result
The Query I would like to create
var upCommingLecture = _context.LectureGigs
.Include(g => g.Artist).Include(g => g.Genre).Where(g => g.IsWeekLy == true && (int)g.Days == (myDayOfWeek))
.Where(g => g.DateTime > DateTime.Now && !g.IsCanceled);
//Error none but 0 result
I have also tried this
var upCommingLecture = _context.LectureGigs
.Include(g => g.Artist).Include(g => g.Genre)
.Where(g => g.DateTime > DateTime.Now && !g.IsCanceled && g.IsWeekLy==true &&(int)g.Days==(myDayOfWeek));
//Error none but 0 result

OR (||), not AND (&&)
var upCommingLecture = _context.LectureGigs
.Include(g => g.Artist).Include(g => g.Genre)
.Where(g => (g.DateTime > DateTime.Now && !g.IsCanceled)
|| (g.IsWeekLy==true &&(int)g.Days==(myDayOfWeek)));

Related

convert SQL with subquery to LINQ (lamda expression)

Need help with converting this sql query
SELECT c.studentId, c.Name
FROM Classes c
WHERE c.Class = 'Math'
AND c.Grade IN 'yoklama', '2')
AND c.studentId IN (
SELECT c2.studentId
FROM Classes c2
WHERE c2.Class = 'Eng'
AND c.Grade IN ('yoklama', '2'))
I was trying like this but these keeps giving error that I am doing this wrong
var reportDtos = context.Classes.Where(c => pt.Class == 'Math' && c.Grade.HasValue
&& c.Grade == '2' || c.Grade == 'yoklama' && c.studentId.Contains(context.ParticipTests
.Where(x => x.Class == 'Math' &&x.Grade.HasValue && x.Grade == '2' || x.Grade == 'yoklama')
.ToList()
.Select(x => ))
.Include("Area")
.Include("Questions")
.Include("Class.Test")
.ToList()
.Select(pt => new ReportDto
{
...
}
First off, strings must always be double quoted " and not single quoted ' like you have some.
If you write some code by splitting up the steps it makes it more understandable.
var validGrades = new List<string> { "Yoklama", "2" };
var studentsInEnglish = context.ParticipTests
.Where(x => x.Class.Equals("Eng") && validGrades.Contains(x.Grade))
.Select(x => x.studentId);
var studentsInMath = context.Classes
.Where(x => x.Class.Equals("Math") && validGrades.Contains(x.Grade) && studentsInEnglish.Contains(x.studentId))
.Select(x => (x.studentId, x.Name));
Now with this, (if you really still want to) you can write a single query by plugging in and replacing.
var reportDtos = context.ParticipTests
.Where(
x => x.Class.Equals("Math") &&
new List<string> { "Yoklama", "2" }.Contains(x.Grade) &&
context.Classes
.Where(
y => y.Class.Equals("Eng") &&
new List<string> { "Yoklama", "2" }.Contains(y.Grade))
.Select(y => y.studentId)
.Contains(x.studentId))
.Select(x => (x.studentId, x.Name))
.ToList();
...But I like the first way better.

Use same, looked-up value across multiple linq Where clauses without looking up more than once

I have a LINQ query which has three Where clauses. In each Where clause I am looking up the same set of items in order to compare values:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Where(x => level1Category == 0 || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Contains(level1Category))
.Where(x => !level2Categories.Any() || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Intersect(level2Categories.AsEnumerable()).Any())
.Where(x => !level3Categories.Any() || x
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id).Intersect(level3Categories.AsEnumerable()).Any());
Is there a way I can get the value of UmbracoAlias.Items.Categories once and store that value to be used in the other where clauses without causing the GetPropertyValue method to execute more than once?
You can pair up each item with category IDs, like this:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Select(c => new {
Child = c
, CategoryIds = c
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id)
.ToList()
})
.Where(x => level1Category == 0 || x.CategoryIds.Contains(level1Category))
.Where(x => !level2Categories.Any() || x.CategoryIds.Intersect(level2Categories.AsEnumerable()).Any())
.Where(x => !level3Categories.Any() || x.CategoryIds.Intersect(level3Categories.AsEnumerable()).Any())
.Select(x => x.Child);
This does the filtering on children paired up with their category IDs, and then keeps only the Child object in the final projection.
You could further simplify this by combining all three Where clauses:
var items = _umbracoHelper.GetPage(ItemsPage.ModelTypeAlias).Children
.Where(c => {
var categoryIds = c
.GetPropertyValue<IEnumerable<IPublishedContent>>(UmbracoAlias.Item.Categories)
.Select(y => y.Id)
.ToList();
if (level1Category != 0 && !categoryIds.Contains(level1Category)) {
return false;
}
if (level2Categories.Any() && !categoryIds.Intersect(level2Categories.AsEnumerable()).Any()) {
return false;
}
if (level3Categories.Any() && !categoryIds.Intersect(level3Categories.AsEnumerable()).Any()) {
return false;
}
return true;
});

how to show result using multiple Order by descending using linq query

I am having 3 criteria. I want to order these 3 types.
Who Paid with Master User
Who Update their Post Latest Date
Who Paid with Sub Master User
which one is having count it will come to top 15 Jobs.
My code here:
var orderMaster= _vasRepository.GetOrderDetails()
.Where(od => od.OrderMaster.OrganizationId != null &&
od.OrderId == od.OrderMaster.OrderId &&
od.OrderMaster.PaymentStatus == true &&
od.ValidityTill.Value >= currentdate)
.OrderByDescending(od => od.ValidityTill)
.Select(ord => ord.OrderMaster.Id.Value);
var updatedVacancyList = _repository.GetJobs()
.Where(c => c.UpdatedDate != null &&
updateFresh <= c.UpdatedDate)
.Select(c => c.Id);
var orderLatestUser = _vasRepository.GetOrderDetails()
.Where(od => od.OrderMaster.UserId != null &&
od.OrderMaster.PaymentStatus == true &&
freshUser <= od.ActivationDate &&
od.ValidityTill.Value >= currentdate)
.Select(c => c.OrderMaster.User.Id);
Then I check the count of those then assign to
List<int> lstMasterId = orderOrganization.ToList();
List<int>lstUpdatedJobsListId = updatedVacancyList.ToList();
List<int>lstUserListId= orderLatestUser.ToList();
Here i order the lists using query
Func<IQueryable<Job>, IOrderedQueryable<Job>> orderingFunc = query =>
{
if (orderMaster.Count() > 0)
return query.OrderByDescending(rslt =>
lstOrganizationId.Contains(rslt.OrganizationId))
.ThenByDescending(rslt=>lstUserListId.Contains(rslt.User.Id))
.ThenByDescending(rslt => lstUpdatedJobsListId.Contains(rslt.Id))
.ThenByDescending(rslt => rslt.CreatedDate);
else
return query.OrderByDescending(rslt => rslt.CreatedDate);
};
jobs = orderingFunc(jobs);
}
I want to show the lstUserListId at top of the result.. How to do this?

linq query for selecting records which have first rank

I have a table in which i have multiple rows with same PayFrequencyId .
my sql query is which is working for me OK is as follow
SELECT *
FROM (SELECT payfrequencyid,
customname,
payfromdate,
paytodate,
checkdate,
Rank()
OVER(
partition BY payfrequencyid
ORDER BY payfromdate) AS 'RowRank'
FROM payfrequencycalendar
WHERE ispaid = 0
AND companyid = 3) AS T
WHERE rowrank = 1
but i have to use this in linq.
I have tried something like this but its not working for me .
IList<IPayFrequencyCalendar> objPayFrequencyInfo =
objPayFrequencyManager.GetAll()
.Where(x =>
x.CompanyId == SessionWrapper.CompanyId
&& x.IsPaid == false)
.GroupBy(o => o.PayFrequencyId)
.OrderBy(x => x.PayFromDate).Take(5).ToList();
Try this :
IList<IPayFrequencyCalendar> objPayFrequencyInfo =
objPayFrequencyManager.GetAll()
.Where(x => x.CompanyId == SessionWrapper.CompanyId
&& x.IsPaid == false)
.GroupBy(o => o.PayFrequencyId)
.Select(g => g.OrderBy(t => t.PayFromDate).First())
.ToList();

OrderByDescending doesn't work in nested linq statement

In Linqpad, i can see the correct list. But in code, after putting in the list collection, order by doesn't work for BeginDate. If i use BeginDate with Max, it works. I don't understand where i am wrong?
var templist = contentRepository
.Get(q => (q.Status == (int)StatusEnum.Active) &&
(q.CategoryId == category.GetHashCode() || q.Category.ParentId == category.GetHashCode())
&& q.MinorVersion == 0
&& q.MajorVersion > 0)
.GroupBy(q => q.VersionId)
.OrderByDescending(q => q.Key)
.Select(q => new
{
VersionId = q.Key,
Id = q.Max(x => x.Id),
MajorVersion = q.Max(x => x.MajorVersion),
UpdatedAt = q.Max(x => x.UpdatedAt),
//BeginDate = q.Max(x=>x.BeginDate),
BeginDate = (q.OrderByDescending(x => x.Id).Take(1).Select(x=>x.BeginDate)).First(),
Title = (q.OrderByDescending(x => x.Id).Take(1).Select(x => x.Title)).First(),
ShowOnHomePage = (q.OrderByDescending(x => x.Id).Take(1).Select(x=>x.ShowOnHomePage)).First()
})
.OrderByDescending(x => x.BeginDate)
.Take(maxItemCount)
.ToList();
List<ContentEntity> contents = new List<ContentEntity>();
templist.ForEach(q => contents.Add(
contentRepository
.Get(x => x.VersionId == q.VersionId && x.MajorVersion == q.MajorVersion && x.MinorVersion == 0)
.FirstOrDefault()
));
return contents.Where(q => q.ShowOnHomePage == true)
.OrderByDescending(q => q.MajorVersion)
.OrderByDescending(q => q.BeginDate)
.Take(maxItemCount)
.ToList();
You are ordering by Id, not by BeginDate. Equivalent code for
q.Max(x => x.BeginDate)
Will be
q.OrderByDescending(x => x.BeginDate).Take(1).Select(x => x.BeginDate).First()
Or simplified
q.OrderByDescending(x => x.BeginDate).First().BeginDate

Categories

Resources