Rewrite a LINQ Query - entity-framework

I have this query:
List<string> cat = new List<string>{'2'.'3','44'};
var storeEn = query1.AsEnumerable().
Where(ca => ca.CategoriesIds.Split(',',StringSplitOptions.None).
Any(x => cat.Contains(x)));
It is running but it is slow. Is there a way to change this query?

Related

MongoDB .NET Group by with list result of whole objects

I was digging into the documentation of MongoDB http://mongodb.github.io/mongo-csharp-driver/2.7/reference/driver/crud/linq/ and I saw, using .NET drive is possible to make group by on the database.
For 1 ProductId I can have few elements in a database. I want to get whole Last element.
So I am trying to do something like:
var query = _collection.AsQueryable()
.GroupBy(p => p.ProductId, (k, s) =>
new { Name = k, Result = s.First() })
.Select(x => new { Name = x.Name, Result = x.Result }).First();
The problem is that I see an error message like:
System.NotSupportedException: Specified method is not supported.
at
MongoDB.Driver.Linq.Processors.AccumulatorBinder.GetAccumulatorArgument(Expression node)
I know that for now in my example i didnt order by the result.. But this will be my second step. For now i see that i cannot group by. Is it possible to do this kind of group by?
My solution for that is:
var query = _collection.Aggregate(new AggregateOptions { AllowDiskUse = true })
.Match(x => ElementIds.Contains(x.ElementId))
.SortByDescending(x => x.StartDate).ThenByDescending(x => x.CreatedAt)
.Group(x => x.ElementId, x => new
{
StartDate = x.First().StartDate,
Grades = x.First().Grades,
SellingId = x.First().SellingId,
CreatedAt = x.First().CreatedAt,
ModifiedAt = x.First().ModifiedAt,
Id = x.First().Id,
ElementId = x.First().ElementId
})
.ToEnumerable(token);
After that, I parsed it into my model.
AllowDiskUse = true, because in my case MongoDB's memory is not enough to handle this operation.

Evaluate EF query with MAX on the server

Using Entity Framework Core 2.2 I have the following query:
var user = await context.Users.AsNoTracking()
.Include(x => x.Lessons).ThenInclude(x => x.LessonLevel)
.FirstOrDefaultAsync(x => x.Id == userId);
var lessons = context.Lessons.AsNoTracking();
.Where(x => x.LessonLevelId < user.Lessons.Max(y => y.LessonLevelId));
Thus query evaluates locally and I get the message:
The LINQ expression 'Max()' could not be translated and will be evaluated locally.'
How can I make this query evaluate on the server?
Update
Based on DavigG answer I made it work using:
var maxLessonLevelId = user.Lessons.Max(y => y.LessonLevelId););
var lessons = context.Lessons.AsNoTracking();
.Where(x => x.LessonLevelId < maxLessonLevelId);
I know the following evaluates locally but shouldn't evaluate on the server?
var lessons = context.Lessons.AsNoTracking();
.Where(x => x.LessonLevelId <
context.Users.AsNoTracking()
.Where(y => y.Id == userId)
.Select(y => y.Lessons.Max(z => z.LessonLevelId))
.FirstOrDefault());
Is it possible to use a child queries that evaluates on the server?
Get the max value as a separate query, for example:
var maxLessonLevelId = user.Lessons.Max(y => y.LessonLevelId);
Then you can can get the lessons like this:
var lessons = context.Lessons.AsNoTracking()
.Where(x => x.LessonLevelId < maxLessonLevelId);

Find maximum value of all properties in list of objects

I have the following Entity Framework Core query:
IQueryable<Product> products = context.Products;
var maximums = new MaximumModel {
PA = await products.MaxAsync(x => x.Composition.PA)
PB = await products.MaxAsync(x => x.Composition.PB)
PC = await products.MaxAsync(x => x.Composition.PC)
PD = await products.MaxAsync(x => x.Composition.PD)
// Other 36 properties ...
}
This executes 40 queries, one for each query ...
Is there a way to execute only one query?
I haven't tested this with EF async versions, but the LINQ to SQL solution is to use a singleton group from a GroupBy to combine the query into one query:
var maximums = await products.GroupBy(p => 1)
.Select(pg => new MaximumModel {
PA = pg.Max(x => x.Composition.PA),
PB = pg.Max(x => x.Composition.PB),
PC = pg.Max(x => x.Composition.PC),
PD = pg.Max(x => x.Composition.PD),
// Other 36 properties ...
}).FirstAsync();

Can we use a DbContext within a Linq Select Expression?

Is it a good practice or a convention to use dbContext within a Select linq query as following . If not what is the right convention or alternative to do so ?
dbContext.Employees.Select(x=>{
**Name = dbContext.ContactInformation.Where(y=>y.Id = x.Id),**
Id = x.Id
})
Why do not you have a navigationPropery from Employee to ContactInformation? look here
var result = dbContext.Employees.Include(e => e.ContactInformation);
You can also use a Join.
var res = dbContext.Employees.Join(ContactInformation,
e => e.Id,
c => c.Id,
(e, c) => new { e, c })
.Select(ec => ec.e);

Query without condition in MongoDB + C#

I'm trying to use the collection.FindAndModify and give it a IMongoQuery which selects all the documents. But I can not find how to create a query without any conditions!
Can anyone tell me how to do this? I'm using MongoDB C# Driver v1.8.3.
Here's my code:
var query = ???;
var sortBy = SortBy.Ascending(new string[] { "last_update" });
var update = Update<Entity>.Set(e => e.last_update, DateTime.Now);
var fields = Fields.Include(new string[] { "counter", "_id" });
var m = collection.FindAndModify(query, sortBy, update, fields, false, false);
I wonder what should I write in place of ??? to select all the documents!?
Use an empty QueryDocument:
var query = new QueryDocument();
But keep in mind that FindAndModify will only modify the first matching document.