I want to load from a specific id the list include details with lambda.
I tried it with following code:
// Load User Visitor list
var list = await Context.UserVisitors
.Where(s => s.UserId.Equals(userOwner.Id))
.Select(s => s.UserVisitorId)
.ToListAsync();
foreach (var t in list)
{
UserOwnerVisitors.Add(await Context.User
.Include(u => u.Details)
.Include(u => u.Settings)
.FirstAsync(u => u.Id.Equals(t)));
}
The code works, but it is not efficient. How I can do it in one request with lambda?
Thanks in advance.
I am a little bit blind, as I don't know all your model's relationship, but below you can find what I think is your model, if you edit your question I can perhaps give you an exact answer:
var UserOwnerVisitorsList = from uv in Context.UserVisitors
join u in Context.User
on uv.UserId equals u.Id
join det in Context.Details
on det.UserId equals u.Id
join set in Context.Settings
on set.UserId equals u.UserId
where uv.UserId == userOwner.Id
select u;
Related
I'm using ASP.NET Core MVC 2.*, and using McirosoftEntityFrameworkCore.
I have following tables with relation in parentheses:
Categories(1<==>*)CategoryProduct(*<==>1)Products(1<==>*)AttributeProduct(*<==>1)Attributes(*<==>1)AttributeCategories
I want to create a dynamic filter box in my app which my ViewModel for filter box is as following:
Category(Children==>)AttributeCategories(Children==>)Attributes(Children==>)ProductAttributeValues
I'm using Entity Attribute Value for my "ProductAttribute" table.
The queries which I've tried are as follow:
Using LINQ:
var linqQuery = from c in _context.Categories
join cp in _context.CategroyProducts on c.Id equals cp.CategoryId
join p in _context.Products on cp.ProductId equals p.Id
join pa in _context.ProductAttributes on p.Id equals pa.ProductId
join a in _context.Attributes on pa.AttributeId equals a.Id
join ac in _context.AttributeCategories on a.AttributeCategoryId equals ac.Id
where c.Id == categoryId
This query need to use multiple group by which is challenging for me.
Using Include and foreach:
var includeQuery= _context.Categories
.Include(x => x.CategroyProducts)//step1
.ThenInclude(x => x.Product)//step2
.ThenInclude(x => x.ProductAttributes)//step3
.ThenInclude(x => x.Attribute)//step4
.ThenInclude(x => x.AttributeCategory);//step5
The challenge in this query is to going from step1==>step5==>step4==>step3, which I can't achieve that in foreach.
What is the best way to fill the ViewModel?
Good day,
Thanks for your time.
I want to get the latest messages of a chat table by userId and projectId and this is working fine
select * from chatTable inner join
(select max(SendDate) maxtime,[ProjectId] from [chatTable]
group by [ProjectId])latest
on latest.maxtime=chatTable.SendDate and
latest.[ProjectId]=chatTable.[ProjectId]
order by SendDate
As you can see, I am getting the latest messages from the chatTable , with a join that brings the latest project id and the latest message.
How can I have a linq with extension methods?
var messages= await _dbContext.chatTable.....
Thanks
You can first query the inner part like below:
var latest= _dbContext.chatTable.GroupBy(x=>x.ProjectId).Select(x=>new {maxTime=x.Max(y=>y.SendDate), ProjectId=x.Key });
var res=(from ct in _dbContext.ChatTable
join la in latest on la.maxTime equals ct.SendDate and la.ProjectId equals ct.ProjectId).ToList().OrderBy(x=>x.SendDate);
This query should do what you want
_dbContext.ChatTable
.GroupBy(c => c.ProjectId)
.Select(g => g
.OrderByDescending(c => c.SendDate)
.First())
.OrderBy(c => c.SendDate);
This should give what you need:
_dbContext.chatTable
.GroupBy(c => c.ProjectId)
.Select(g => g.OrderBy(c => c.SendDate).LastOrDefault())
Well guys, it seems that linq entity framework has its advantages
this query is better and gets the latest message sent to the latest project
var ultimos = await _dbContext.chatTable .GroupBy(item => item.ProjectId)
.Select(group => new { pId= group.Key, latestMessage= group.OrderByDescending(r=>r.SendDate)
.FirstOrDefault() })
.ToListAsync();
and all the messages are inside the entity
I need to get NewsImage field and list of categories Ids that associated with the news in Many to Many relationship ... but it gives me error:
The type of one of the expressions in the join clause is incorrect.Type inference failed in the call to 'Join'.
My code looks like this
var Result1 = (from c in db.News
join d in db.Categories
on c.NewsId equals d.News.Select(l => l.NewsId)
where c.NewsId == 1
select new { c.NewsImagePath, d.CategoryId }).ToList();
Assuming you have a navigation property defining the n-n relation I would write:
var result = db.News
.Where(x => x.NewsId == 1)
.SelectMany(x => x.Categories,
(news, category) => new { news.NewsImagePath, category.CategoryId })
.ToList();
The problem is inside the on statement.
on c.NewsId equals d.News.Select( l => l.NewsId )
The Select on the right-hand side will return a IEnumerable of news, which is not what you want.
Something like this would technically work:
on c.NewsId equals d.News.Select( l => l.NewsId ).FirstOrDefault()
But it does not make sense logically.
I suspect the whole query should be built differently. I think you want to join when the category list of news contains the news item. In that case, you can't use the join statement, it would look somewhat like this:
from n in db.News
from c in db.Categories
where c.News.Select( ne => ne.NewsId ).Contains( n.NewsId )
select new { n.NewsImagePath, c.CategoryId }
var query2 = (from tc in Entities.TutorCourses
join c
in Entities.Course
on tc.CourseId equals c.Id
where tc.CourseId == id
select tc.Username).ToList();
var query1 = Entities.User
.Select(u => u.Role
.Select(p => p.Name)
.Contains("Tutor"));
I am trying to return all the Users from a database that are in query1 except all those Users that are in query2 as above.
How can I achieve this? I tried using returning query1 by adding .Except(query2); in the end but I am not sure which is the best method to implement a 'NOT IN' function in LINQ
That 2nd query just looks wrong. Try this:
var query2 = (from tc in Entities.TutorCourses
join c
in Entities.Course
on tc.CourseId equals c.Id
where tc.CourseId == id
select tc.Username).ToList();
var query1 = Entities.User
.Where(u =>
query1.Any(un => un != u.Username) &&
u.Role.Name.Contains("Tutor"))
.Select(u => u.Role);
If this all query are the same type try to you this method
Intersect
You can use the Any to find matches between two lists, then add a ! to specify that you want the ones that don't match. Here's an example that should work for you:
var excludedList = query1.Where(x => !query2.Any(y => y.Id == x.Id));
How about query1.Where(c=> !query2.Contains(c));
I have a LINQ, it works fine. My question is: how to convert it to Lambda Expression?
var searchResults = from study in dataContext.Studies
join location in dataContext.Locations
on study.LocationID equals location.LocationID
join doctorLocation in dataContext.DoctorLocations
on location.LocationID equals doctorLocation.LocationID
join doctor in dataContext.Doctors
on doctorLocation.DoctorID equals doctor.DoctorID
where doctor.DoctorID == doctorId
select study;
I think LINQ is more natural to me (similar to SQL script). However, in this case, I just want to convert it to Lambda Expression, but I could not make it work.
I got stuck at:
var searchResults = dataContext.Studies.Where(x =>
x.Location.DoctorLocations.FirstOrDefault() != null &&
x.Location.DoctorLocations.FirstOrDefault().DoctorID == doctorId);
This only works for FirstOrDefault. Since there are multiple DoctorLocations, I do not how to write this one.
Try this:
var searchResults = dataContext.Studies.Where(x =>
x.Location != null
&& x.Location.DoctorLocations.Any(dl => dl.DoctorID == doctorId));
you will get all Studies related to at least one DoctorLocation with DoctorID equals doctorId
var searchResults = dataContext.Studies
.Include(x => x.Locations)
.Include(x => x.DoctorLocations)
.Include(x => x.Doctors)
.Where(x => x.[InheritedPathToDoctor].DoctorId == id)
.Select(x => x.[InheritedPathToStudy].Study)
.FirstOrDefault() OR .ToList()
I have made a lot of assumptions here as to how you have set up your context. I've assumed it's a relational database and therefore the includes simply means it returns all data. I haven't tested it though so there are probably a few errors.
You require an include for every class and the where is pretty self explanatory.