InvalidOperationException: The LINQ expression '' could not be translated - entity-framework

var baseQuery = Context.Questions.AsNoTracking().Where(x => x.Active && x.QuestionFoils.Any());
// Gets 30
baseQuery = baseQuery.Where(x => x.QuestionReferences.Any());
//Gets 2
baseQuery = baseQuery.Where(
x => x.QuestionReferences.Any(qr =>
listNames.Any(name =>
name.FirstName == qr.Reference.ReferenceProfessors.Professor.FirstName &&
name.LastName == qr.Reference.ReferenceProfessors.Professor.LastName
)));
countCount = baseQuery.Count();
When I try to do any operation on the query, it gives a InvalidOperationException: The LINQ expression '' could not be translated.
InvalidOperationException: The LINQ expression
'Any, ReferenceProfessor>, Professor>>( source:
LeftJoin, ReferenceProfessor>, Professor, Nullable,
TransparentIdentifier, ReferenceProfessor>, Professor>>( outer:
LeftJoin,
ReferenceProfessor, Nullable,
TransparentIdentifier, ReferenceProfessor>>( outer: Join, TransparentIdentifier>( outer: Where( source:
DbSet, predicate: (q2) =>
Property>(EntityShaperExpression: EntityType: Question
ValueBufferExpression: ProjectionBindingExpression:
EmptyProjectionMember IsNullable: False , "QuestionId") ==
Property>(q2, "QuestionId")), inner: DbSet,
outerKeySelector: (q2) => Property>(q2, "ReferenceId"),
innerKeySelector: (r) => Property>(r, "ReferenceId"),
resultSelector: (o, i) => new TransparentIdentifier( Outer = o, Inner = i )), inner: DbSet,
outerKeySelector: (q2) => Property>(q2.Inner,
"ReferenceId"), innerKeySelector: (r0) => Property>(r0,
"ReferenceId"), resultSelector: (o, i) => new
TransparentIdentifier, ReferenceProfessor>( Outer = o, Inner = i )), inner:
DbSet, outerKeySelector: (q2) =>
Property>(q2.Inner, "ProfessorId"), innerKeySelector:
(p) => Property>(p, "ProfessorId"), resultSelector: (o,
i) => new
TransparentIdentifier, ReferenceProfessor>, Professor>( Outer = o, Inner = i )),
predicate: (q2) => Any( source: (Unhandled parameter:
__listNames_0), predicate: (name) => name.FirstName == q2.Inner.FirstName && name.LastName == q2.Inner.LastName))' could not
be translated. Either rewrite the query in a form that can be
translated, or switch to client evaluation explicitly by inserting a
call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or
ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for
more information.
Anything with a single table works just fine:
baseQuery = baseQuery.Where(x => x.QuestionCourses.Any(qc => courses.Any(name => name == qc.Course.Name)));
How would I rewrite the following to not throw this error?
x => x.QuestionReferences.Any(qr =>
listNames.Any(name =>
name.FirstName == qr.Reference.ReferenceProfessors.Professor.FirstName &&
name.LastName == qr.Reference.ReferenceProfessors.Professor.LastName
))

I believe the issue will be that you are trying to filter the Linq expression with an object with 2 fields (name.FirstName & name.LastName) which won't translate down to SQL. EF can translate list contains/any into IN clauses, but against a singular field/expression.
What should work:
Combine your names into a single list of strings. For instance "FirstName LastName" or "LastName, FirstName" then combine the professor name when comparing:
x => x.QuestionReferences.Any(qr =>
listNames.Any(name => name == qr.Reference.ReferenceProfessors.Professor.FirstName
+ " " + qr.Reference.ReferenceProfessors.Professor.LastName ))
Where listNames = "FirstName LastName";

Related

Flutter Sort list by 3 properties

I have a List with some properties and I would like two sort all of them by three properties. In my list I have number, number2, date and some other properties. When I click on number list sort by number ASC, when I click again on number list sort DESC by number. When I click again on number, do not sort by number. Same for number2 and date. But When I click on number and then on number2, sort by both fields. Same for date
I tried like this but does not work for me.
All fields are ASC order
reports.sort((a, b) => <Comparator<Reports>>[
(o1, o2) => o1.number.compareTo(o2.number),
(o1, o2) => o1.number2.compareTo(o2.number2),
(o1, o2) => o1.date.compareTo(o2.date),
].map((e) => e(a, b)).firstWhere((e) => e != 0, orElse: () => 0));
Number field is DASC order other are ASC order
reports.sort((a, b) => <Comparator<Reports>>[
(o1, o2) => o2.number.compareTo(o1.number),
(o1, o2) => o1.number2.compareTo(o2.number2),
(o1, o2) => o1.date.compareTo(o2.date),
].map((e) => e(a, b)).firstWhere((e) => e != 0, orElse: () => 0));
Tried like this but does not work. If anyone have idea please help.

Slick how to sort by a option column got from left join

At first, get all the children comments in a subquery
val getChildCommentStatQuery =
Tbcomments
.filter(row =>
row.itargetid === commentTargetId && row.iparentid =!= 0 && row.istatus === statusNormal)
.groupBy(_.iparentid)
.map { case (parentId, group) =>
// return parent commentId,the number of all the children,and the sum of like of all the children
(parentId, group.size, group.map(_.ilikecount).sum)
}
Secondly, use Table Tbcomments to left join with subquery table got in the first step.
val query =
Tbcomments
.joinLeft(getChildCommentStatQuery)
.on(_.iid == _._1)
.filter { case (comments, _) =>
// got the first level comment whose parentid equals to 0
comments.itargetid === commentTargetId && comments.iparentid === 0 && comments.istatus === statusNormal
}
.map { case (comments, childComments) =>
val replyCount = childComments.map(_._2)
val likeCountSum = comments.ilikecount + childComments.map(_._3.getOrElse(0))
val hot = replyCount + likeCountSum
val support = comments.ilikecount - comments.inotlikecount
(comments.iid, replyCount, likeCountSum, hot, support, comments.dtcreated)
}
.sortBy(row =>
sortOrder match {
case LATEST_COMMENT_ORDER => row._6.desc
case EARLIEST_COMMENT_ORDER => row._6.asc
case SUPPORT_COMMENT_ORDER => row._5.desc
// case HEAT_COMMENT_ORDER => row._4.get
})
The problem is, the row._4 is a field aggregate based on right table, and in the left join case it's an option. It seems can't sortBy the option field directly.
Thanks!

EF Core aggregation query

I use EF Core 5 and this query throws an exception. Id and EntityId are uniqueidentifiers in both tables.
query:
var records = await (from r in _dbContext.Set<MedicalRecord>()
join d in _dbContext.Set<Document>()
on r.Id equals d.EntityId into grouping
select new { r, DocumentCount = grouping.Count() }).ToListAsync();
here is an exception:
System.InvalidOperationException: The LINQ expression 'DbSet<MedicalRecord>()
.GroupJoin(
inner: DbSet<Document>(),
outerKeySelector: r => r.Id,
innerKeySelector: d => d.EntityId,
resultSelector: (r, grouping) => new {
r = r,
DocumentCount = grouping
.AsQueryable()
.Count()
})' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'.
Thank you

EF Core GroupBy query throws: could not be translated

Can anyone point me at the faux pas in this EF Core query?
var employers = await iqDbContext.Payrolls
.GroupBy(p => p.PayeScheme.Employer, p => p)
.Select(group => new EmployerViewModel
{
Id = group.Key.Id,
Name = group.Key.Name
})
.ToListAsync();
throws:
System.InvalidOperationException: The LINQ expression 'DbSet<Payroll>()
.Join(
inner: DbSet<PayeScheme>(),
outerKeySelector: p => EF.Property<Nullable<int>>(p, "PAYR_fk1_PAYE_SCHEME"),
innerKeySelector: p0 => EF.Property<Nullable<int>>(p0, "Id"),
resultSelector: (o, i) => new TransparentIdentifier<Payroll, PayeScheme>(
Outer = o,
Inner = i
))
.Join(
inner: DbSet<Employer>(),
outerKeySelector: p => EF.Property<Nullable<int>>(p.Inner, "PychFk1Employer"),
innerKeySelector: e => EF.Property<Nullable<int>>(e, "Id"),
resultSelector: (o, i) => new TransparentIdentifier<TransparentIdentifier<Payroll, PayeScheme>, Employer>(
Outer = o,
Inner = i
))
.Where(p => p.Inner != null && __accessiblePayrollIds_0.Contains(p.Outer.Outer.Id))
.GroupBy(
keySelector: p => p.Inner,
elementSelector: p => p.Outer.Outer)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?
If you need correct grouping, you have to specify which columns to group, not whole object.
var employers = await iqDbContext.Payrolls
.GroupBy(p => new { p.PayeScheme.Employer.Id, p.PayeScheme.Employer.Name })
.Select(group => new EmployerViewModel
{
Id = group.Key.Id,
Name = group.Key.Name,
})
.ToListAsync();

Entity Framework join with a partially hardcoded "on" due to key value pair?

So I have this:
db.Table1
.Join(db.Table2, t1 => t1.id, t2 => t2.id, (t1, t2) => new { t1, t2 })
But what I need to do is join with an attribute value / key value table as well and for a specific attribute like:
SELECT * FROM Table1 t1
JOIN Table2 t2 ON t1.id = t2.id AND t2.attributeid = 123
How do I qualify that attributeid = 123 part?
A Where clause should suffice:
db.Table1
.Join(db.Table2, t1 => t1.id, t2 => t2.id, (t1, t2) => new { t1, t2 })
.Where(x => x.t2.attributeId == 123);
Ideally Table1 should have a navigation property to Table2: (either HasOne or HasMany)
Singular Table2:
var result = db.Table1
.Include(x => x.Table2)
.Where(x => x.Table2.AttributeId == 123);
or for a collection of Table2s...
var result = db.Table1
.Include(x => x.Table2s)
.Where(x => x.Table2s.Any(t2 => t2.AttributeId == 123);
which would return any Table1 containing a Table2 with that attribute...
or with a collection that you want to filter the Table2s:
var result = db.Table1
.Where(x => x.Table2s.Any(t2 => t2.AttributeId == 123)
.Select(x => new
{
Table1 = x,
FilteredTable2s = x.Table2s.Where(t2 => t2.AttributeId == 123).ToList()
});