Full text + spatial search with Entity Framework 4 - entity-framework

Let's say I have a SQL 2005 database with a table called Restaurants. The Restaurants table has the following columns:
RestaurantId
Name
Latitude
Longitude
I want to let users search for restaurants by name and/or address. How do I write the LINQ query to support this? I need to be able to support the possibility that the user doesn't enter in a name or address, just the name, just the address, or both name and address.
My initial idea was to write a stored procedure to calculate the distance between two lat/long pairs and a table value function for calling FREETEXTTABLE and using some conditional Join calls on my query. However, it appears that Entity Framework 4 doesn't support table value functions.

You certainly can write a proc which returns entity types. Indeed, in EF 1 that was the only option for procs. The proc returns a set of values, not a table, but I can't see that you actually need this.
You can also do free-form T-SQL in EF 4 using Context.ExecuteStoreQuery.

You cannot write any LINQ that supports geospatial queries at this point of time - be it EF or LinqToSql. This is because there is no LINQ syntax which can handle the special ST<whatever> spatial syntax that exists in SQL Server 2008. (eg. STIntersects(..))
You will need to write a Stored Procedure which you can then get access to via EF.
If you wish to return a Sql GEOGRAPHY field in a result, you will need to return a VARBINARY(MAX) i think as the equivalent field type for the C# code.
Hope This Helps.

Related

How can I prevent SQL injection with arbitrary JSONB query string provided by an external client?

I have a basic REST service backed by a PostgreSQL database with a table with various columns, one of which is a JSONB column that contains arbitrary data. Clients can store data filling in the fixed columns and provide any JSON as opaque data that is stored in the JSONB column.
I want to allow the client to query the database with constraints on both the fixed columns and the JSONB. It is easy to translate some query parameters like ?field=value and convert that into a parameterized SQL query for the fixed columns, but I want to add an arbitrary JSONB query to the SQL as well.
This JSONB query string could contain SQL injection, how can I prevent this? I think that because the structure of the JSONB data is arbitrary I can't use a parameterized query for this purpose. All the documentation I can find suggests I use parameterized queries, and I can't find any useful information on how to actually sanitize the query string itself, which seems like my only option.
For example a similar question is:
How to prevent SQL Injection in PostgreSQL JSON/JSONB field?
But I can't apply the same solution as I don't know the structure of the JSONB or the query, I can't assume the client wants to query a particular path using a particular operator, the entire JSONB query needs to be freely provided by the client.
I'm using golang, in case there are any existing libraries or code fragments that I can use.
edit: some example queries on the JSONB that the client might do:
(content->>'company') is NULL
(content->>'income')::numeric>80000
content->'company'->>'name'='EA' AND (content->>'income')::numeric>80000
content->'assets'#>'[{"kind":"car"}]'
(content->>'DOB')::TIMESTAMP<'2000-01-30T10:12:18.120Z'::TIMESTAMP
EXISTS (SELECT FROM jsonb_array_elements(content->'assets') asset WHERE (asset->>'value')::numeric > 100000)
Note that these don't cover all possible types of queries. Ideally I want any query that PostgreSQL supports on the JSONB data to be allowed. I just want to check the query to ensure it doesn't contain sql injection. For example, a simplistic and probably inadequate solution would be to not allow any ";" in the query string.
You could allow the users to specify a path within the JSON document, and then parameterize that path within a call to a function like json_extract_path_text. That is, the WHERE clause would look like:
WHERE json_extract_path_text(data, $1) = $2
The path argument is just a string, easily parameterized, which describes the keys to traverse down to the given value, e.g. 'foo.bars[0].name'. The right-hand side of the clause would be parameterized along the same rules as you're using for fixed column filtering.

EF SQL WHERE using LOWER() conversion for string comparison

My application is using Entity Framework over a SQL Azure Database.
It has a feature that allows the the user to search for records based on a given phone number. The table being searched has many columns, including 3 columns for phone numbers: a BusinessPhone, a HomePhone and a CellPhone column. All three of these columns are indexed.
My EF DbContext is generating the following as part of the WHERE clause:
WHERE (10 = [Extent1].[Debtor_DebtorStatus]) AND
(((LOWER([Extent1].[BusinessPhone])) = (LOWER(N'012345678')))
OR ((LOWER([Extent1].[HomePhone])) = (LOWER(N'012345678')))
OR ((LOWER([Extent1].[CellPhone])) = (LOWER(N'012348678')))
)
The query is taking about 3 minutes to return a response (even when I run it in SQL Management Studio).
If I edit this SQL statement and remove the LOWER() function, then it executes in less than a second!!!
Is there some setting I can flick to make EntityFramework NOT use the LOWER() function in the generated SQL statement?
Of if that is not possible, is there a way I can intercept this SQL statement and remove the LOWER() functions in code before execution on the database?

How to use "DISTINCT ON (field)" in Doctrine 2?

I know how to use "DISTINCT" in Doctrine 2, but I really need to use "DISTINCT ON (field)" and I don't know how to do this with the QueryBuilder.
My SQL query looks like:
SELECT DISTINCT ON (currency) currency, amount FROM payments ORDER BY currency
And this query works perfect, but I can't use it with the QueryBuilder. Maybe I could write this query on some other way?
I would suggest that the SELECT DISTINCT ON (..) construct that PostgreSQL supports is outside the Object Relational Model (ORM) that is central to Doctrine. Or, perhaps put another way, because SELECT DISTINCT ON (..) is rare in SQL implementations Doctrine haven't coded for it.
Regardless of the actual logic for it not working, I would suggest you try Doctrine's "Native SQL". You need to map the results of your query to the ORM.
With NativeQuery you can execute native SELECT SQL statements and map
the results to Doctrine entities or any other result format supported
by Doctrine.
In order to make this mapping possible, you need to describe to
Doctrine what columns in the result map to which entity property. This
description is represented by a ResultSetMapping object.
With this feature you can map arbitrary SQL code to objects, such as
highly vendor-optimized SQL or stored-procedures.
SELECT DISTINCT ON (..) falls into vendor-optimized SQL I think, so using NativeQuery should allow you to access it.
Doctrine QueryBuilder has some limitations. Even if I didn't check if it's was possible with query builder, I do not hesitate to use DQL when I do not know how to write the query with query builder.
Check theses examples at
http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html#dql-select-examples
Hope this help.
INDEX BY can be used in DQL, allowing first result rows indexed by the defined string/int field to be overwritten by following ones with the same index:
SELECT
p.currency,
p.amount
FROM Namespace\To\Payments p INDEX BY p.currency
ORDER BY p.currency ASC
DQL - EBNF - INDEX BY

stored procedure returns data of varying dimensions Entity Framework 4

for the reporting of a survey system I am working on, we developed a stored procedure that returns data with varying number of columns.
we show the operator all the columns from these tables: Users, Questions, Answers.
the user selects the columns from each of the tables that the report should show.
for example:
User: Name, Age, zipcode.
Questions: question2, question 4
Answers: answer2, answer3, answer4.
we then pass the parameters to the stored procedure and the stored procedure returns:
one column for each user property, question or answer.
and a row for each user in the DB.
example:
as you can see, the stored procedure can return anything between 3 rows of 2 columns to 500 rows of 50 columns. Is there a way to use the stored procedure with entity framework? at first I tried with a complex return type, but it appears that that approach will not work in this case.
EF supports only stored procedures with fixed number of columns defined at design time. To execute this procedure you need to use plain old ADO.NET.
EDIT: If you have fixed total nuber of colums (you mentioned 50) you can create single class containing all these columns and use it as result for execution. EF will fill only properties existing in the result set.

Using table names as parameters in t-sql (eg from #tblname)

Is it possible to use the name of a table as a parameter in t-sql?
I want to insert data into a table, but I want one method in C# which has a parameter for the table.
Is this a good approach? I think if I have one form and I am choosing the table and fields to insert data into, I am essentially looking to write my own dynamic sql query built on the fly. This is another thing altogether which I am sure has its catches?
Thanks
Not directly. The only way to do this is through dynamic SQL - either EXEC or sp_ExecuteSQL. The latter has the advantage of query cache/re-use, and avoiding injection via parameters for the values - but you will have to concatenate the table-name itself into the query (you can't parameterise it), so be sure to white-list it against a list of known-good table names.