Linq To Sql - Dynamic - linq-to-sql

I have two Tables:
Table 1: Client
Fields: Id_Client Char 5 Name_Client
Char 50
Table 2: Country
Fields: Id_Country Char 4 Name_Country
Char 80 Population Int 15
With Sql I can make this 2 queries
Select Id_Client, Name_Client from
Client
Select Id_Country, Name_Country,
Population from Country
I wan to do this 2 queries in only one using Linq SQL.
I think something like this
string Option = "";
string SelectFields = ""; string
TableName = "";
if (Option == "Client"){
SelectFields = "Id_Client, Name_Client";
TableName = "Client";
}
else{
SelectFields = "Id_Country, Name_Country, Population";
TableName = "Country";
}
Select "SelectFields" from "TableName"
I'm a Visual Fox Pro Developer and using Evaluate (macros) this is very easy to do. Is possible to do something like this on Linq To Sql???
Sorry for my poor english

You will want to look into dynamic linq to sql, this will allow you to pass in the expression as a string.
In the end you will end up with something like the following:
IQueryable<SomeItem> = results = context.SomeItem.Where("SomeItemID > 30 AND SomeItemID < 40");
Additional Information, Using Dynamic Linq

Related

mysql use case in jpa query

I am building an endpoint where 3 query param comes in request like
status(mendatory)
searchCriteria(optional)
startDate(optional)
I am considering that i have to write three(3) native sql queries with combination of ex.
1: status and searchCriteria
2: status and startDate
3: status and searchCriteria and startDate
but I do not want to write three queries,
I know it is possible to achieve in a single query using case .
This is my native sql query
#Query(value = "select * from email_info u where u.status =:status and u.campaign =:searchCriteria and u.scheduleat =:startDate",
nativeQuery = true)
object getPromotional(String status, String searchCriteria, String startDate);
How to use case in above query using jpa like
CASE
WHEN :searchCriteria != null THEN u.campaign =:searchCriteria
WHEN :startDate != null THEN u.scheduleat =:startDate
END

What's wrong with this SQL query WHERE AND clause?

Previously, this was working:
$patient_story_set_photos = $wpdb->get_results('SELECT * FROM wp_before_after WHERE patientID = '.$post->ID.' AND patient_display = 1');
However, when I try to add another AND condition like this:
$patient_story_set_photos = $wpdb->get_results('SELECT * FROM wp_before_after WHERE patientID = '.$post->ID.' AND patient_display = 1 AND period_taken = '.$set->period_taken);
I get the following error on screen:
WordPress database error: [Unknown column '1hour' in 'where clause']
SELECT * FROM wp_before_after WHERE patientID = 8175 AND patient_display = 1 AND period_taken = 1hour
Can't see why there's a problem, are you not allowed to use multiple AND conditions in SQL?
The problem is not the AND, the problem is your 1hour, 1hour unquoted means a reference to an object (database, table) named 1hour, you need to quote '1hour'.
If you write
SELECT * FROM wp_before_after
WHERE patientID = 8175
AND patient_display = 1
AND period_taken = '1hour'
you will compare the field periodtaken to a string (CHAR,VARCHAR,TEXT) equal to '1hour'.
I assume period_taken is a field typed CHAR,VARCHAR or TEXT
Before anything, DO NOT CONCATENATE SQL STRINGS nowadays it is a MUST (see how to do it properly https://stackoverflow.com/a/60496/3771219)
The problem you are facing is because, I presume, that the period_taken field is some sort of Char/Varchar/String field and when you are filtering by a "Stringy" field you must sorround your literals values with single quotes:
SELECT *
FROM wp_before_after
WHERE patientID = 8175
AND patient_display = 1
AND period_taken = '1hour'
Hope this help

Complex MySQL query issue

I have a somewhat complex mySQL query I am trying to execute. I have two parameters: facility and isEnabled. Facility can have a value of "ALL" or be specific ID. isEnabled can have value of "ALL" or be 0/1.
My issue is that I need to come up with logic that can handle the following scenarios:
1) Facility = ALL AND isEnabled = ALL
2) Facility = ALL AND isEnabled = value
3) Facility = someID AND isEnabled = ALL
4) Facility = someID AND isEnabled = value
The problem is that I have several nested IF statements:
IF (Facility = 'ALL') THEN
IF (isEnabled = 'ALL') THEN
SELECT * FROM myTable
ELSE
SELECT * FROM myTable
WHERE isEnabled = value
END IF;
ELSE
IF (isEnabled = 'ALL') THEN
SELECT * FROM myTable
WHERE facility = someID
ELSE
SELECT * FROM myTable
WHERE facility = someID AND isEnabled = value
END IF;
END IF;
I would like to be able to combine the logic in the WHERE clause using either a CASE statement or Conditional's (AND/OR) but I am having trouble wrapping my head around it this morning. Currently the query is not performing as it is expected to be.
Any insight would be helpful!
Thanks
You could do this...
SELECT
*
FROM
myTable
WHERE
1=1
AND (facility = someID OR Facility = 'ALL')
AND (isEnabled = value OR isEnabled = 'ALL')
However, this yields a poor execution plan - it's trying to find one size fits all, but each combination of parameters can have different plans depending on data, indexes, etc.
This means that it is better to build the query dynamically
SELECT
*
FROM
myTable
WHERE
1=1
AND facility = someID -- Only include this line if : Facility = 'ALL'
AND isEnabled = value -- Only include this line if : isEnabled = 'ALL'
I know it can feel dirty to use dynamic queries, but this is a good corner case as to when then really can excel. I'll go find a spectacularly informative link for you now. (It's a lot to read, but it's very worth learning from)
Link : Dynamic Search

Advanced Search in Linq to SQL possible?

Without the use of "LIKE" in Dynamic Linq it virtually renders it useless to me when trying to create an advanced search query.
How have any of you overcome this Advanced Search problem when using Linq to SQL?
I'd need to search the following field types and they all could be null as well:
List item
varchar (column LIKE '%' + myText + '%')
text (column LIKE '%' + myText + '%')
DateTime (column >= myDate - if the "myDate" is not null of course)
integer (column = myInt - if "myInt" is not null of course)
boolean
I also can't just use ExecuteQuery because then I don't get a true "entity" and all of it's relations/associations.
I just don't see how I can do this with Linq to SQL. I'm currently without Stored Procs so I'd rather not have one stored proc just for this if I can figure this out with Linq.
To make LIKE Statements, you can use the Contains method:
string myText = "test";
var query = dc.Table.Where(r=>r.Column.Contains(myText));
This will generate this kind of SQL Statement:
SELECT [t0].[Column], ... [t0].[ColumnN]
FROM [Table] AS [t0]
WHERE [t0].[Column] LIKE #p0
And the #p0 parameter will have "%test%" as value.
For the Date and int comparison if I understand correctly what do you want, you could do this:
DateTime? myDate = new DateTime(2009, 3, 15);
var query = dc.Table.Where(r=> r.DateColumn > myDate || myDate == null );
So, if myDate is null, the condition DateColumn > myDate wont be evaluated.

MySQL, select records with at least X characters matching

I am trying to accomplish the following. Let's say we have a table that contains these fields (ID, content)
1 | apple
2 | pineapple
3 | application
4 | nation
now, I am looking for a function that will tell me all possible common matches. For example, if the argument is "3", the function will return all possible strings from 3 characters that appear in more then one record.
In this case, I get "app","ppl","ple","ati","tio","ion"
If the argument is "4", i get: "appl","pple","atio","tion"
If the arugment is "5", i get: "apple","ation"
If the argument is "6", nohting is returned.
Untill now, I did not find a function that accomplishes this.
Thx!
Some extra information:
I am using this in a PHP script with a MySQL database. I really just want to give the amount of characters as an argument and of course the table to search in.
Well, this is kind of ugly, but it does work fine. It's generic SQL and will work in any environment. Simply generate a number of selects of a substring that is greater than the maximum length of the field that you're reading. Change the number 50 in the function to a number that exceeds your fieldlength. It may return a realllly long query, but like I said, it'll work fine. Here is an example in Python:
import sqlite3
c = sqlite3.connect('test.db')
c.execute('create table myTable (id integer, content varchar[50])')
for id, content in ((1,'apple'),(2,'pineapple'),(3,'application'),(4,'nation')):
c.execute('insert into myTable values (?,?)', [id,content])
c.commit();
def GenerateSQL(substrSize):
subqueries = ["select substr(content,%i,%i) AS substr, count(*) AS myCount from myTable where length(substr(content,%i,%i))=%i group by substr(content,%i,%i) " % (i,substrSize,i,substrSize,substrSize,i,substrSize) for i in range(50)]
sql = 'select substr FROM \n\t(' + '\n\tunion all '.join(subqueries) + ') \nGROUP BY substr HAVING sum(myCount) > 1'
return sql
print GenerateSQL(3)
print c.execute(GenerateSQL(3)).fetchall()
The query generated looks like:
select substr FROM
(select substr(content,0,3) AS substr, count(*) AS myCount from myTable where length(substr(content,0,3))=3 group by substr(content,0,3)
union all select substr(content,1,3) AS substr, count(*) AS myCount from myTable where length(substr(content,1,3))=3 group by substr(content,1,3)
union all select substr(content,2,3) AS substr, count(*) AS myCount from myTable where length(substr(content,2,3))=3 group by substr(content,2,3)
union all select substr(content,3,3) AS substr, count(*) AS myCount from myTable where length(substr(content,3,3))=3 group by substr(content,3,3)
union all select substr(content,4,3) AS substr, count(*) AS myCount from myTable where length(substr(content,4,3))=3 group by substr(content,4,3)
... )
GROUP BY substr HAVING sum(myCount) > 1
And the results it produces are:
[(u'app',), (u'ati',), (u'ion',), (u'nat',), (u'pin',), (u'ple',), (u'ppl',), (u'tio',)]
I'm sorry as I haven't been playing with php for a while & I don't have a proper test environment for it, but I quickly devised a way of doing this in c# 3.5
pseudocode: build a table with strings of the specified length & a count of occurences next to it. Select where count > 1:
static void Main(string[] args)
{
string[] data = { "apple", "pinapple", "application", "nation" };
string[] result = my_func(3,data);
foreach (string str in result)
{
Console.WriteLine(str);
}
Console.ReadKey();
}
private static string[] my_func(int l, string[] data)
{
Dictionary<string,int> dict = new Dictionary<string,int>();
foreach (string str in data)
{
for (int i = 0; i < str.Length - l + 1; i++)
{
string part = str.Substring(i, l);
if (dict.ContainsKey(part))
{
dict[part]++;
}else {
dict.Add(part,1);
}
}
}
var result = from k in dict.Keys
where dict[k] > 1
orderby dict[k] descending
select k;
return result.ToArray<string>();
}
One obvious option is to use REGEX. I have no prior experience in this but this might be of help to you:
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
You'll need to find a suitable expression to match what you need.