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
Related
Tell me how can I write a query to update a field with a nested query using quill?
The query that should be the result:
UPDATE table1 SET field = 'foo' WHERE id IN (SELECT id FROM table2 WHERE field IN (value1, value2))
In quill it loks like:
val table1 = quote(querySchema[Table1]("table1"))
val table2 = quote(querySchema[Table2]("table2"))
val params = List("param1", "param2")
quote{
table1
.filter(t => table2.filter(t2 => liftQuery(params).contains(t2.field))
.map(_.id)
.contains(t.id)
)
.update(_.field -> lift("foo"))
}
The compiler tells me that I will get the right request, but I keep getting an error.
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();
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";
Sql:
select a.id, b.name
from a
left join b on a.id = b.id
I want to use lambda in EF to get the same result in this sql
Here is what I've done:
var list = entities.a
.GroupJoin(
entities.b,
a => a.id,
b => b.id,
(a, b) => new { a, b })
.Select(o => o)
.ToList();
Here Select(o => o), I just don't know how to get the same result in sql
select a.id, b.name
I think this article from MSDN would be a lot helpful...
http://msdn.microsoft.com/en-us/library/bb397895.aspx
This is a quote from above article, that might help...
var query = from person in people
join pet in pets on person equals pet.Owner into gj
from subpet in gj.DefaultIfEmpty()
select new { person.FirstName, PetName = (subpet == null ? String.Empty : subpet.Name) };
UPDATE:
As per your request, the Lambda Expression would be something like this...
.SelectMany(#a => #a.#a.b.DefaultIfEmpty(), (#a, joineda) => new {#a, joineda})
Not sure, if it is correct, but it is a starting point, at least...
I am writing function that encapsulate query in lambda expression and i wanted to return query result in the form of array but it is giving error on the last line of code:- Error is following:-
Cannot implicitly convert type 'AnonymousType#1[]' to 'double[]
query is following which is giving above error on last line of code:
public double[] PopulateGrid()
{
using (var db = new hdContext())
{
var query = db.tickets.Join(
db.employees, t => t.CreatedBy, e => e.EmployeeId, (t, e) => new
{
t.Id,
t.EmployeeName,
e.Employee_Name,
e.Department,
e.Location,
t.Subject,
t.MainCatId,
t.SubCatId,
t.PickTicket,
t.Status,
t.CreateDate
}).Join
(
db.MainCategory, t => t.MainCatId, m => m.MainCatId, (t, m) => new
{
t.Id,
t.EmployeeName,
t.Employee_Name,
t.Department,
t.Location,
t.Subject,
t.MainCatId,
m.MainCatName,
t.SubCatId,
t.PickTicket,
t.Status,
t.CreateDate
}).ToArray();
return query;
}
}
It's not clear what you're trying to do. The last parameter of the Join method is the result selector (which determines what the query returns), and in your case you're returning an anonymous type:
new
{
t.Id,
t.EmployeeName,
t.Employee_Name,
t.Department,
t.Location,
t.Subject,
t.MainCatId,
m.MainCatName,
t.SubCatId,
t.PickTicket,
t.Status,
t.CreateDate
}
Obviously you can't convert this type to a double, so you probably want to select a specific field using .Select(z => z.MyDoubleField) before materializing your entities with ToArray()