Full Text Search with LINQ, decrease results with each keyword - c#

I followed the directions in this SO question to create a linq function to do a full text search on a food database i have. there are over 7000 records in this DB and with each keyword i add the results get larger as opposed to smaller.
here is the meat of my function:
SELECT *
FROM USDA_Foods AS FT_TBL
INNER JOIN FREETEXTTABLE(USDA_Foods,
Shrt_Desc,
#searchWord) AS KEY_TBL
ON FT_TBL.foodId = KEY_TBL.[KEY]
How would i decrease the results with each new keyword by altering the code above?
Thanks

You get more results because it works looking for any of the words in the searched column, and not that contains all of the words, as you expect. You can't use AND or anything in FREETEXTTABLE, so you have to use something like CONTAINSTABLE, which allows you to use AND between the provided words.
CONTAINSTABLE (Transact-SQL)
Look at the example "I. Using CONTAINS with a logical operator (AND)" here:
CONTAINS (Transact-SQL)
The syntax is valid also for CONTAINSTABLE.
SELECT *
FROM USDA_Foods AS FT_TBL
INNER JOIN CONTAINSTABLE(USDA_Foods,
Shrt_Desc,
#searchWord) AS KEY_TBL
ON FT_TBL.foodId = KEY_TBL.[KEY]
Your #searchWord should look like
'here AND there AND everywhere'
to look for text that contains here, there and everywhere.

Concatenate INNER JOINS for each search word.
SELECT *
FROM USDA_Foods AS FT_TBL
INNER JOIN FREETEXTTABLE(USDA_Foods,
Shrt_Desc,
#searchWord1) AS KEY_TBL1
ON FT_TBL.foodId = KEY_TBL1.[KEY]
INNER JOIN FREETEXTTABLE(USDA_Foods,
Shrt_Desc,
#searchWord2) AS KEY_TBL2
ON FT_TBL.foodId = KEY_TBL2.[KEY]

Related

How to write a LEFT OUTER JOIN where the right side is null in LINQ to SQL?

How do you write a LEFT OUTER JOIN in LINQ to SQL, where the right side is null?
A graphical representation of the result I want would be this:
Image credits Jeff Atwood.
Take this SQL for example:
select Document.*
from Document left outer join Invoice
on Document.DocumentId = Invoice.DocumentId
where Invoice.DocumentId is null
Basically I want all documents that are not invoices but some other kind of document, doesn't matter what.
I would greatly appreciate examples in both LINQ Query Syntax and LINQ Method (Fluent) Syntax.
Thank you!
Firstly, even in SQL that query should really be a not exists, it is generally more efficient than the left join / is null construct.
The compiler also understands exists better, as it understands that the not exists cannot add more rows to the resultset, so it can keep any uniqueness guarantee that may be there. The compiler does not see that left join with an is null check cannot add rows (perhaps it should, but there is no logic currently built into it to do so).
select Document.*
from Document
where not exists (select 1
from Invoice
where Document.DocumentId = Invoice.DocumentId);
Now it's obvious how to do it in Linq:
var docs =
from doc in Documents
where !Invoices.Any(inv => doc.DocumentId == inv.DocumentId);
var docs =
Documents
.Where(doc => !Invoices.Any(inv => doc.DocumentId == inv.DocumentId));

Regex matching SQL with subqueries, indicate by bracket [duplicate]

I need to write RegEx in C# to parse SQL join query which is given as a string. Can somebody please help me because I'm new at this. Thanks a lot
this is my problem:
string query = #"SELECT table1.column1, table1.column2, table2.coulmn1, table2.column2
FROM table1 INNER JOIN table2 ON table1.column5 = table2.column5";
what I actually need is to put all important data into separate variables, like this:
string class1 = table1
string class2 = table2
string joinForeignKey1 = table1.column5
string joinForeignKey2 = table2.column5
List<string> attributes1 = table1.column1, table1.column2
List<string> attributes2 = table2.column1, table2.column2
//COMMENT
I realized that I have made a mistake in sql query so there will be an ON clause.
I can force a user to provide me with the correct syntax, so that will be no problem.
The thing I haven't mentioned is that there can be more than one JOIN ON clause (multiple joins).
Thanks a lot and I will appreciative any given help.
Pulling this over from comments, since I think it's the right answer here:
SQL is #3 on the list of Stuff You Should Not Try To Parse With A Regex, just behind HTML and MUMPS. Use a dialect-specific, dedicated SQL parser, not a regex.
I personally do not recommend doing this unless you have a VERY, VERY valid reason to do so as well as full control over the way that the SQL would be written.
First and foremost the syntax that you noted for the SQL statement is the old style join syntax and not using the more common ON syntax.
Something like
SELECT A.ColumnA, B.ColumnB
FROM MyTable A
INNER JOIN YourTable B
ON (A.MyIdentity = B.MyForeignKey)
So unless you can force users to input queries in the old syntax you are already going down the road to a way that will not work.
If I was forced to do this type of thing, and I did have control over it, I personally wouldn't bother with RegEx, due to the fact that the process is so structured. i would just use basic string manipulation.

RegEx for parsing SQL query in C#

I need to write RegEx in C# to parse SQL join query which is given as a string. Can somebody please help me because I'm new at this. Thanks a lot
this is my problem:
string query = #"SELECT table1.column1, table1.column2, table2.coulmn1, table2.column2
FROM table1 INNER JOIN table2 ON table1.column5 = table2.column5";
what I actually need is to put all important data into separate variables, like this:
string class1 = table1
string class2 = table2
string joinForeignKey1 = table1.column5
string joinForeignKey2 = table2.column5
List<string> attributes1 = table1.column1, table1.column2
List<string> attributes2 = table2.column1, table2.column2
//COMMENT
I realized that I have made a mistake in sql query so there will be an ON clause.
I can force a user to provide me with the correct syntax, so that will be no problem.
The thing I haven't mentioned is that there can be more than one JOIN ON clause (multiple joins).
Thanks a lot and I will appreciative any given help.
Pulling this over from comments, since I think it's the right answer here:
SQL is #3 on the list of Stuff You Should Not Try To Parse With A Regex, just behind HTML and MUMPS. Use a dialect-specific, dedicated SQL parser, not a regex.
I personally do not recommend doing this unless you have a VERY, VERY valid reason to do so as well as full control over the way that the SQL would be written.
First and foremost the syntax that you noted for the SQL statement is the old style join syntax and not using the more common ON syntax.
Something like
SELECT A.ColumnA, B.ColumnB
FROM MyTable A
INNER JOIN YourTable B
ON (A.MyIdentity = B.MyForeignKey)
So unless you can force users to input queries in the old syntax you are already going down the road to a way that will not work.
If I was forced to do this type of thing, and I did have control over it, I personally wouldn't bother with RegEx, due to the fact that the process is so structured. i would just use basic string manipulation.

Joins and subqueries in LINQ

I am trying to do a join with a sub query and can't seem to get it. Here is what is looks like working in sql. How do I get to to work in linq?
SELECT po.*, p.PermissionID
FROM PermissibleObjects po
INNER JOIN PermissibleObjects_Permissions po_p ON (po.PermissibleObjectID = po_p.PermissibleObjectID)
INNER JOIN Permissions p ON (po_p.PermissionID = p.PermissionID)
LEFT OUTER JOIN
(
SELECT u_po.PermissionID, u_po.PermissibleObjectID
FROM Users_PermissibleObjects u_po
WHERE u_po.UserID = '2F160457-7355-4B59-861F-9871A45FD166'
) used ON (p.PermissionID = used.PermissionID AND po.PermissibleObjectID = used.PermissibleObjectID)
WHERE used.PermissionID is null
Without seeing your database and data model, it's pretty impossible to offer any real help. But, probably the best way to go is:
download linqpad - http://www.linqpad.net/
create a connection to your database
start with the innermost piece - the subquery with the "where" clause
get each small query working, then join them up. Linqpad will show you the generated SQL, as well as the results, so build your small queries up until they are right
So, basically, split your problem up into smaller pieces. Linqpad is fantastic as it lets you test these things out, and check your results as you go
hope this helps, good luck
Toby
The LINQ translation for your query is suprisingly simple:
from pop in PermissibleObjectPermissions
where !pop.UserPermissibleObjects.Any (
upo => upo.UserID == new Guid ("2F160457-7355-4B59-861F-9871A45FD166"))
select new { pop.PermissibleObject, pop.PermissionID }
In words: "From all object permissions, retrieve those with at least one user-permission whose UserID is 2F160457-7355-4B59-861F-9871A45FD16".
You'll notice that this query uses association properties for navigating relationships - this avoids the need for "joining" and simplfies the query. As a result, the LINQ query is much closer to its description in English than the original SQL query.
The trick, when writing LINQ queries, is to get out of the habit of "transliterating" SQL into LINQ.

Simple Join

This question is about subsonic
I am trying to build a select query HAVING joins in it using subsonic.
For Example if I want to extract data from 3 tables then how I will be able to do it in Subsonic.
Lets say if I have a TSQL given below then How I will be able to translate this into Subsonic?
Select la.LoanAppId, ci.FirstName, ci.LastName, la.ApplicationDateSubmitted,
la.LoanAmount, la.DueDate, lkUpD.Col1Value
from LoanApplication la, ContactInfo ci, LookUpDetails lkUpD
where la.UserId = ci.UserId
and la.StatusId = lkUpD.LookUpDetailId
Please Reply
SubSonic.SqlQuery q = new Select(
LoanApplication.LoanAppId, ContactInfo.FirstNa, [etc])
.From(LoanApplication.Schema)
.InnerJoin(ContactInfo.Schema)
.InnerJoin(LookUpDetails.Schema);
if all the inner joins are natural (else, you need to add more .InnerJoin calls to specify the inner-join conditions).

Categories