What the linq query for SQL like and Soudex for sql server 2008? - linq

In sql server, we can issue sql to get data like
select * from table where column like '%myword%'
select * from person where Soundex(LastName) = Soundex('Ann')
what's the linq query to match above sql?

from t in table
where t.column.Contains("myword")
select t
In .Net 4.0 you can use the SoundCode function, probably like this:
from p in person
where SqlFunctions.SoundCode(p.LastName) == SqlFunctions.SoundCode('Ann')
select p

you may want to use the difference function
http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.difference%28VS.100%29.aspx
you could also create your own
https://web.archive.org/web/1/http://blogs.techrepublic%2ecom%2ecom/programming-and-development/?p=656

Related

Oracle not using index, Entity Framework & Devart DotConnect for oracle

The table in question has ~30mio records. Using Entity Framework I write a LINQ Query like this:
dbContext.MyTable.FirstOrDefault(t => t.Col3 == "BQJCRHHNABKAKU-KBQPJGBKSA-N");
Devart DotConnect for Oracle generates this:
SELECT
Extent1.COL1,
Extent1.COL2,
Extent1.COL3
FROM MY_TABLE Extent1
WHERE (Extent1.COL3 = :p__linq__0) OR ((Extent1.COL3 IS NULL) AND (:p__linq__0 IS NULL))
FETCH FIRST 1 ROWS ONLY
The query takes about four minutes, obviously a full table scan.
However, handcrafting this SQL:
SELECT
Extent1.COL1,
Extent1.COL2,
Extent1.COL3
FROM MY_TABLE Extent1
WHERE Extent1.COL3 = :p__linq__0
FETCH FIRST 1 ROWS ONLY
returns the expected match in 200ms.
Question: Why is it so? I would expect the query optimizer to note that the right part is false if the parameter is not null, so why doesn't the first query hit the index?
Please set UseCSharpNullComparisonBehavior=false explicitly:
var config = Devart.Data.Oracle.Entity.Configuration.OracleEntityProviderConfig.Instance;
config.QueryOptions.UseCSharpNullComparisonBehavior = false;
If this doesn't help, send us a small test project with the corresponding DDL script so that we can investigate the issue.

How to ignore collation when comparing Á to a

I'm working on a migration of a SQL from mysql to redshift. One of the columns is a utf8 characters (not mb4). For simplicity the SQL looks like:
SELECT *
FROM a
JOIN b
ON a.name = b.name;
The table's data looks like:
a:
Name
a
b:
Name
Á
With the given data and SQL above, in MySQL the SQL will return one row. Where redshift will not. I was trying to do collate(a.name,'case_insensitive') = collate(b.name,'case_insensitive') but it made no difference.
Really hope anyone have an advice for me how I can make this same behavior as MySQL?
I did not find builtin solution, so I made one:
CREATE OR REPLACE FUNCTION unaccent_string(text)
RETURNS text
IMMUTABLE
LANGUAGE SQL
AS $$
SELECT translate(
$1,
'ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿĀāĂ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌōŎŏŐőŒœŔŕŖŗŘřŚśŜŝŞşŠšŢţŤťŦŧŨũŪūŬŭŮůŰűŲųŴŵŶŷŸŹźŻżŽžſ',
'AAAAAAACEEEEIIIIENOOOOOOUUUUYPsaaaaaaaceeeeiiiienoooooouuuuypyAaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIiJjKkkLlLlLlLlLlNnNnNnnNnOoOoOoOoRrRrRRSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZzs'
);
$$;
Then I could do:
SELECT *
FROM a
JOIN b
ON upper(unaccent_string(a.name)) = upper(unaccent_string(b.name));

PostgreSQL - migrate a query with 'start with' and 'connect by' in oracle

I have the following query in oracle. I want to convert it to PostgreSQL form. Could someone help me out in this,
SELECT user_id, user_name, reports_to, position
FROM pr_operators
START WITH reports_to = 'dpercival'
CONNECT BY PRIOR user_id = reports_to;
A something like this should work for you (SQL Fiddle):
WITH RECURSIVE q AS (
SELECT po.user_id,po.user_name,po.reports_to,po.position
FROM pr_operators po
WHERE po.reports_to = 'dpercival'
UNION ALL
SELECT po.user_id,po.user_name,po.reports_to,po.position
FROM pr_operators po
JOIN q ON q.user_id=po.reports_to
)
SELECT * FROM q;
You can read more on recursive CTE's in the docs.
Note: your design looks strange -- reports_to contains string literals, yet it is being comapred with user_id which typicaly is of type integer.

How can I convert sql to linq

This is my SQL query
SELECT
sys.sysobjects.name Name,
sys.foreign_keys.*
FROM
sys.foreign_keys
inner join sys.sysobjects on
sys.foreign_keys.parent_object_id = sys.sysobjects.id
WHERE
referenced_object_id = OBJECT_ID(N'[dbo].[Country]')
I have installed Linqer to convert SQL to linq.
But I got an error:
SQL cannot be converted to LINQ: Table [foreign_keys] not found in the current Data Context.
I am a beginner in Linq. Can Anyone help me to convert SQL to Linq
The problem is that system views will not be picked up by Linqer. If you want to read these tables in your application, first create your own views on them, as was done here and write a query on these views.
CREATE VIEW SysObjectsView AS SELECT * FROM sys.sysobjects;
GO
CREATE VIEW SysForeignKeysView AS SELECT * FROM sys.foreign_keys;
GO
SELECT obj.name Name, fk.*
FROM SysForeignKeysView fk
INNER JOIN SysObjectsView obj ON fk.parent_object_id = obj.id
INNER JOIN SysObjectsView objfk ON fk.referenced_object_id = objfk.id
WHERE objfk.name = N'Country'
Linqer should be able to pick up these views.

Need help converting a Linq query (Silverlight RIA Entity - Oracle DB)

I have no problem with SQL, but I'm finding Linq a little confusing.
C#, .NET4, Silverlight, RIA services, Oracle DB (v?), VS2010 running Devart dotConnect 6.10.121.
I have a RIA Entity
public sealed partial class ProcessLogHdr : Entity
{
DateTime JobDate;
string InterfaceName;
int SuccessfulCount;
int FailCount;
int TotalCount;
}
There are more fields such as user, etc, that won't be applicable to this post.
There are many jobs that make up a process. Each job has an entry in this table, but the view I want is a date group by summary.
I will be calling context.Load on a query, where I pass in the start and end date, which in Oracle looks like this:
select
trunc(JobDate),
InterfaceName,
sum(SuccessfulCount) as Total_Pass,
sum(FailCount) as Total_Fail,
sum(TotalCount) as Total,
max(JobDate) as Last_Msg_Processed_At_DT
from
ProcessLogHdrsEntity
where
JobDate >= START_DATE_IN_VAR and
JobDate <= END_DATE_IN_VAR
group by
trunc(JobDate),
InterfaceName
order by
trunc(JobDate) desc,
InterfaceName asc;
conttext.Load will call the linq query from a method that returns IQueryable.
The linq statement must run for Oracle under Devart dotConnect for Oracle.
I'm guessing I need some custom class to hold the results, like ProcessLogHdrDateSummary.
If you guys could help me fill in the missing ????? linq, I would be so grateful:
public IQueryable<ProcessLogHdrDateSummary> GetProcessLogHdrsDateSummary(DateTime START_DATE_IN_VAR, DateTime END_DATE_IN_VAR)
{
return ?????
}
Many Thanks!
There's no simple answer to this. One of the characteristics of LINQ to database providers is that some queries execute immediately, while others don't. Aggregation functions (MAX, MIN, etc) return immediately. So do some LINQ functions that specify particular output, such as .First(). Anything returning a collection will likely not execute immediately, and will return an IQueryable<> of some type.
What type? That depends on what the select clause of the LINQ statement specifies (which is not the same as the generated SQL select clause). "from c in db.customers select c" returns customer objects, but you can also use the select clause to populate other classes, or anonymous classes.
If a LINQ query returns an IQueryable<>, remember that the query hasn't executed yet! It won't execute until you start processing the data. You must process the data while still in scope of the data context, because once that's gone, you've lost your database connection.
You can always force an IQueryable<> to execute by ending it with .ToList(), .ToArray(), .ToDictionary(), or a few others. The List<> will use the same generic type as the IQueryable<> and the select clause (or .Select() method) of the LINQ statement.
The LINQ query will be rather complicated. I recommend that you follow these steps:
1. Create a stored procedure with an out cursor:
CREATE PROCEDURE myQuery(
DATE START_DATE_IN_VAR,
DATE END_DATE_IN_VAR,
cur out sys_refcursor) AS
BEGIN
OPEN cur FOR SELECT
trunc(JobDate),
InterfaceName,
sum(SuccessfulCount) as Total_Pass,
sum(FailCount) as Total_Fail,
sum(TotalCount) as Total,
max(JobDate) as Last_Msg_Processed_At_DT
from
ProcessLogHdrsEntity
where
JobDate >= START_DATE_IN_VAR and JobDate <= END_DATE_IN_VAR
group by
trunc(JobDate), InterfaceName
order by
trunc(JobDate) desc, InterfaceName asc;
END;
2. Add this procedure to the model. If you are using Devart Entity model, the return type will probably be generated. In other case you will need to create an entity or a complex type that will represent the return type of the generated method.
3. Treat the method call as a usual DomainService method.

Resources