Entity Framework : OrderBy while using Select extension method - entity-framework

I have a search predicate as follows
{x => (x.Actions.Any(y => (y.Id == 1))}
and sorting expression as below
{x => x.Actions.Select(y => y.Id)}
But every time I try to run this code below I get an exception on the execution of the query (I am using Sql linq provider)
context.Employees.Where(x => (x.Actions.Any(y => (y.Id == 1))).OrderBy(x => x.Actions.Select(y => y.Id)).First();
DbSortClause expressions must have a type that is order comparable.
Does this mean that the Select extension method can't be used with OrderBy method?

Related

InvalidOperationException: The LINQ expression '' could not be translated

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";

Boolean operators in filter of list

I am trying to filter a list of files by two conditions. And the following code works
import java.io.File
val d = new File("/home/loom/shp")
val dirList = d.listFiles.filter(_.isDirectory).toList
dirList.map({
_.listFiles.filter(f => f.isFile).filter(f => f.getName.endsWith("shp")).toList.map(println)
// !! Inducde an error
// _.listFiles.filter((f => f.isFile) && (f => f.getName.endsWith("shp"))).toList.map(println)
})
However, if I tried to combine both conditions in one filter condition (as it is shown in the commented line), I have received the following error message:
Error:(32, 27) missing parameter type
_.listFiles.filter((f => f.isFile) && (f => f.getName.endsWith("shp"))).toList.map(println)
It claims that I missed the parameter type. What should I correct to make my code work?
You're trying to use the boolean && operator on two functions, which simply won't work. What you want is a function from File to Boolean, which you can write like this:
_.listFiles.filter(f => f.isFile && f.getName.endsWith("shp")).toList.map(println)
f.isFile is a boolean and f.getName.endsWith(...) is a boolean, so && will do what you expect.

Composite key and where in in squeryl

How can I write deleteWhere clause in squeryl for entity with composite id?
val list: List[CompositeKey2[Long, Date]] = existing.map(x => x.id).toList
Schema.entities.deleteWhere(q => q.id in list)
Error:(82, 49) value in is not a member of org.squeryl.dsl.CompositeKey2[Long,java.util.Date]
Schema.entities.deleteWhere(q => q.id in list)
^
With a CompositeKey, the id method doesn't map directly to a column, so it isn't useful in an in clause. You'll have to structure your where to reference each column that makes up the private key individually. Without knowing the columns involved it's tough to be more specific, but something like
deleteWhere(q => existing.map(e => q.id1 === e.id1 and q.id2 === e.id2).reduce(_ or _))

Spark: querying Mongodb with Stratio and RDD

I am querying MongoDB with Spark using Stratio (0.11.). I am interested to use RDDs (no DataFrame).
What I am doing right now is:
val mongoRDD = new MongodbRDD(sqlContext, readConfig, new MongodbPartitioner(readConfig))
mongoRDD.foreach(println)
and it displays the collection content in a correct way.
Is there a way to use a query (as String or built via QueryBuilder) with Stratio (in my case the query is $near type) to apply to MongodbRDD?
As #zero323 has hinted, the way to do that is using filters parameter. These filters are checked by the library and matched against the MongoDB QueryBuilder available filters.
From Spark-MongoDB source code:
sFilters.foreach {
case EqualTo(attribute, value) =>
queryBuilder.put(attribute).is(checkObjectID(attribute, value))
case GreaterThan(attribute, value) =>
queryBuilder.put(attribute).greaterThan(checkObjectID(attribute, value))
case GreaterThanOrEqual(attribute, value) =>
queryBuilder.put(attribute).greaterThanEquals(checkObjectID(attribute, value))
case In(attribute, values) =>
queryBuilder.put(attribute).in(values.map(value => checkObjectID(attribute, value)))
case LessThan(attribute, value) =>
queryBuilder.put(attribute).lessThan(checkObjectID(attribute, value))
case LessThanOrEqual(attribute, value) =>
queryBuilder.put(attribute).lessThanEquals(checkObjectID(attribute, value))
case IsNull(attribute) =>
queryBuilder.put(attribute).is(null)
case IsNotNull(attribute) =>
queryBuilder.put(attribute).notEquals(null)
case And(leftFilter, rightFilter) if !parentFilterIsNot =>
queryBuilder.and(filtersToDBObject(Array(leftFilter)), filtersToDBObject(Array(rightFilter)))
case Or(leftFilter, rightFilter) if !parentFilterIsNot =>
queryBuilder.or(filtersToDBObject(Array(leftFilter)), filtersToDBObject(Array(rightFilter)))
case StringStartsWith(attribute, value) if !parentFilterIsNot =>
queryBuilder.put(attribute).regex(Pattern.compile("^" + value + ".*$"))
case StringEndsWith(attribute, value) if !parentFilterIsNot =>
queryBuilder.put(attribute).regex(Pattern.compile("^.*" + value + "$"))
case StringContains(attribute, value) if !parentFilterIsNot =>
queryBuilder.put(attribute).regex(Pattern.compile(".*" + value + ".*"))
case Not(filter) =>
filtersToDBObject(Array(filter), true)
}
As you can see, near is not being applied but it seems like it could be easily added to the connector functionality since QueryBuilder offers methods to use that MongoDB function.
You can try to modify the connector. However I'll try to implement it and make a PR in the following days.
EDIT:
A PR has been opened including a source filter type which describes $near so you can use MongodbRdd as:
val mongoRDD = new MongodbRDD(
sqlContext,
readConfig,
new MongodbPartitioner(readConfig),
filters = FilterSection(Array(Near("x", 3.0, 4.0))))
)

Mongoid syntax for querying based on several sets of attributes

Assuming I want to get 3 documents which fit one of these attributes
Class Question:
name=>a, topic=>b
name=>c, topic=>d
name=>e, topic=>f
What is the appropriate syntax for mongoid to get these?
According to mongoid query syntax:
Model.any_of({:name => a, :topic => b},
{:name => c, :topic => d},
{:name => e, :topic => f})