Can I have a condition in the select of a Linq to Entities query? - ado.net-entity-data-model

I want to do this:
Dim person = From p In context.persons
Order By p.fileNum
Select p.ID,
p.firstName,
p.lastName,
startPenpal = IIf(p.prPenPals.Count > 0,
p.prPenPals.FirstOrDefault.startProfile, "")
I get this error:
LINQ to Entities does not recognize the method 'System.Object IIf(Boolean, System.Object, System.Object)' method, and this method cannot be translated into a store expression.
I tried
Select p.ID, p.firstName, p.lastName,
startPenpal = If(i.prPenPals.Count > 0,
i.prPenPals.FirstOrDefault.startProfile, "")
and I get this error:
Unable to cast the type 'System.DateTime' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types.
Is there a way to do this? prPenpals can contain zero or one record for each record in Persons. There should probablt be a 1 to 0-1 association between persons and prPenPal, but the model has it as a one to many and I haven't been able to change it.

Your mistake is here, I think:
If(i.prPenPals.Count > 0, i.prPenPals.FirstOrDefault.startProfile, "")
You should make sure you will return the same type for the values.
If i.prPenPals.FirstOrDefault.startProfile is a DateTime, then do this:
If(i.prPenPals.Count > 0, i.prPenPals.FirstOrDefault.startProfile, DateAndTime.MinValue)
Not sure about the syntax of VB because I am on C#, but the main idea is the same.

Related

How to return object from user-defined Neo4j function

I have a complicated query like this:
MATCH path = allShortestPaths( ... )
WITH path, reduce(x={
specificStamp: "",
specificCount: 0,
...
},
r IN relationships(path) |
CASE WHEN ...
THEN {
specificStamp: some-expr(x),
specificCount: another-expr(x),
...
}
...
END
) AS pobj
ORDER BY pobj.specificStamp, pobj.specificCount
RETURN head(COLLECT(path)) AS path, pobj.specificStamp AS stamp, COUNT(*) AS cnt
ORDER BY length(path), stamp
The logic in the real code is more complex, including nested CASE and many complex THEN with some duplicating expressions...
To simplify the problem, it would be better to put the reduce logic into a separate function. But Neo4J user defined functions can return only a single value.
Which type of return value corresponds to this cypher expression: {specificStamp: "", specificCount: 0}?
May be Object? But according to the documentation Object means ANY type.
May be Map? But which map template? Map<String,String> conflicts with Map<String,Integer>
Return a Map<String,Integer> or Map<String,Object>
see this for valid types: https://neo4j.com/docs/developer-manual/current/extending-neo4j/cypher-functions/#writing-udf
Map<String,Object> is good enough.
Additional type conversion in the Cypher query is not required.
String field from user function comes as string. Long as long.

ActiveRecord select by last character of string

I tried
members = Member.select(:member_id[6] == "1")
and
members = Member.select(member_id[6]: == "1")
and
members = Member.select("member_id[6]" == "1")
I am trying to get only those members where their member_id final character is a 1.
To get what you want, efficiently, you'll need to leverage Postgres' string functions in a literal SQL condition. Your existing code is also confusing select, the Active Record method that alters what the query uses in its SELECT clause, with select, the Ruby Enumerable method, which allows you to filter a collection. Since your filtering is best performed in the database, you'll want to instead use where.
So, something like:
Member.where("RIGHT(member_id::varchar, 1) = '1'")

When making a query how do you check if the default value was returned?

Using the code below:
let student =
query {
for student in db.Student do
where (student.StudentID = 1)
select student
exactlyOneOrDefault
}
How do you check the value of student, and just what would be the default value if no match in the database was found?
Database objects come from the database library you're using (either LINQ-to-SQL or Entity Framework), they're not originated from F# so they're nullable. The value returned by exactlyOneOrDefault when there isn't exactly one is null.

sanitize_sql_array is adding extra, unnecessary quotes to query

This is the first time I've seen this issue. I'm building up an SQL array to run through sanitize_sql_array and Rails is adding extra, unnecessary single quotes in the return value. So instead of returning:
SELECT DISTINCT data -> 'Foo' from products
it returns:
SELECT DISTINCT data -> ''Foo'' from products
which of course Postgres doesn't like.
Here is the code:
sql_array = ["SELECT DISTINCT %s from products", "data -> 'Foo'"]
sql_array = sanitize_sql_array(sql_array)
connection.select_values(sql_array)
Note the same thing happens when I use the shorter and more usual:
sql_array = ["SELECT DISTINCT %s from products", "data -> 'Foo'"]
connection.select_values(send(:sanitize_sql_array, sql_array))
Ever seen this before? Does it have something to do with using HStore? I definitely need that string sanitized since the string Foo is actually coming from a user-entered variable.
Thanks!
You're giving sanitize_sql_array a string that contains an hstore expression and expecting sanitize_sql_array to understand that the string contains some hstore stuff; that's asking far too much, sanitize_sql_array only knows about simple things like strings and numbers, it doesn't know how to parse PostgreSQL's SQL extensions or even standard SQL. How would you expect sanitize_sql_array to tell the difference between, for example, a string that happens to contain '11 * 23' and a string that is supposed to represent the arithmetical expression 11 * 23?
You should split your data -> 'Foo' into two pieces so that sanitize_sql_array only sees the string part when it is sanitizing things:
sql_array = [ 'select distinct data -> ? from products', 'Foo' ]
sql = sanitize_sql_array(sql_array)
That will give you the SQL you're looking for:
select distinct data -> 'Foo' from products

grails query for distinct entry

Hi I am trying to query my database by a specific property. Multiple entries in my database may have the same value for the property but I want it to return only the first entry that has that distinct value for the property.
For example, if my domain has a code property, then there might be an entry where "code" = "boy", and there might be another one where "code" = "girl" and there might be yet another one where again "code" = "boy". I want to query it so I get the first entry where "code" = "boy" and the entry where "code" = girl" but not the third entry where code is again equal to boy.
I was able to get the distinct code values from the database using both createCriteria() or namedQueries() but I am not able to get the whole object, just the value of code. How can I get the actual object?
Thinking about I came with an HQL query:
select d
from Domain d
where d.id = (select min(d1.id)
from Domain d1
where d1.code = d.code)

Resources