I am developing an web application and using mvc, entity framework, ado.net entity.
I want to know that which one is fast to fetch the data with some conditions :
1. Lambda Expression
2. Linq query
code snipped is below (in below code _dict is dictionary)
string fname = "", username = "", lname = "", mail = "";
if (_dict.ContainsKey("fname"))
fname = _dict["fname"].ToLower();
if (_dict.ContainsKey("username"))
username = _dict["username"].ToLower();
if (_dict.ContainsKey("lname"))
lname=_dict["lname"].ToLower();
if (_dict.ContainsKey("mail"))
mail = _dict["mail"].ToLower();
var _admins = db.AdminsTables.Where(x =>
x.firstname.ToLower().Contains(fname) &&
x.username.ToLower().Contains(username) &&
x.lastname.ToLower().Contains(lname) &&
x.useremail.ToLower().Contains(mail)).ToList();
OR
string fname = "", username = "", lname = "", mail = "";
if (_dict.ContainsKey("fname"))
fname = _dict["fname"].ToLower();
if (_dict.ContainsKey("username"))
username = _dict["username"].ToLower();
if (_dict.ContainsKey("lname"))
lname=_dict["lname"].ToLower();
if (_dict.ContainsKey("mail"))
mail = _dict["mail"].ToLower();
var _admins = (from record in db.AdminsTables
where record.firstname.ToLower().Contains(fname) && record.username.ToLower().Contains(username) && record.lastname.ToLower().Contains(lname) && record.useremail.ToLower().Contains(mail)
orderby record.id descending
select record).ToList();
Please suggest me which one is faster and is possible then give reason also.
In fact you can turn nearly every linq query into a lambda expression. When you working with linq-to-entities or entity-frame work, it doesn't matters if use linq querys or lambda expressions. What matters is the resulting SQL query.
So in your case the first code sample would be faster, because (like #karaxuna already mentioned) you added sorting to the query.
When performance is your focus, you should compare the linq query in code and a sql query in the database. For example:
write a SQL query for the result you want optimize it and look how long it takes
write a LINQ query in code for the same result, look how long it takes
If the SQL query is much faster, you should create a view, a stored procedure and call it from code.
If the measured times are nearly the same, it's up to you if use the LINQ query or create a view, a stored procedure and call it from code.
If the LINQ query is much faster, you should look at the generated SQL query it seems to better than your query.
As far as I experienced, there is only a significant performance difference when you query data which are distributed over multiple tables and need a lot of joins and/or sorting operations.
Related
I have a Linq Query made into a list called "ticket query"
I want to search ticket query for all the records that have specific data
I tried using FindAll() but it gives me an error
Argument matching parameter 'match' cannot convert from
'VB$AnonymousDelegate_1(Of JobPartForm,Nullable(Of Boolean))' to
'Predicate(Of JobPartForm)'.
I can't do the findall directly in the query because its being called at a separate time
is there another way to accomplish this, or am I using find all wrong?
ticketquery = (From ticket In dbContext.JobPartForm
Select ticket).ToList()
Dim formticket = ticketquery.FindAll(Function(f As JobPartForm) f.JobNum = ticketnum And f.FormNumber = formnum)
You can do the same using IQueryable<TSource>.Where method:
Dim formticket=dbContext.JobPartForm.Where((Function(f As JobPartForm) f.JobNum = ticketnum And f.FormNumber = formnum)).ToList();
The first thing is try to never call ToList extension method from a DbSet, that will load your entire table to memory, is really inefficient and more when you can filter your data on the server side.
I am calling a stored procedure from my Groovy code. The stored proc looks like this
SELECT * FROM blahblahblah
SELECT * FROM suchAndsuch
So basically, two SELECT statements and therefore two ResultSets.
sql.eachRow("dbo.testing 'param1'"){ rs ->
println rs
}
This works fine for a single ResultSet. How can I get the second one (or an arbitrary number of ResultSets for that matter).
You would need callWithAllRows() or its variant.
The return type of this method is List<List<GroovyRowResult>>.
Use this when calling a stored procedure that utilizes both output
parameters and returns multiple ResultSets.
This question is kind of old, but I will answer since I came across the same requirement recently and it maybe useful for future reference for me and others.
I'm working on a Spring application with SphinxSearch. When you run a query in sphinx, you get results, you need to run a second query to get the metadata for number of records etc...
// the query
String query = """
SELECT * FROM INDEX_NAME WHERE MATCH('SEARCHTERM')
LIMIT 0,25 OPTION MAX_MATCHES=25;
SHOW META LIKE 'total_found';
"""
// create an instance of our groovy sql (sphinx doesn't use a username or password, jdbc url is all we need)
// connection can be created from java, don't have to use groovy for it
Sql sql = Sql.newInstance('jdbc:mysql://127.0.0.1:9306/?characterEncoding=utf8&maxAllowedPacket=512000&allowMultiQueries=true','sphinx','sphinx123','com.mysql.jdbc.Driver')
// create a prepared statement so we can execute multiple resultsets
PreparedStatement ps = sql.getConnection().prepareStatement(query)
// execute the prepared statement
ps.execute()
// get the first result set and pass to GroovyResultSetExtension
GroovyResultSetExtension rs1 = new GroovyResultSetExtension(ps.getResultSet())
rs1.eachRow {
println it
}
// call getMoreResults on the prepared statement to activate the 2nd set of results
ps.getMoreResults()
// get the second result set and pass to GroovyResultSetExtension
GroovyResultSetExtension rs2 = new GroovyResultSetExtension(ps.getResultSet())
rs2.eachRow {
println it
}
Just some test code, this needs some improving on. You can loop the result sets and do whatever processing...
Comments should be self-explanatory, hope it helps others in the future!
I am trying to avoid a sql injection. This topic has been dealt with in Java (How to prevent query injection on Google Big Query) and Php.
How is this accomplished in App Scripts? I did not find how to add a parameter to a SQL statement. Here is what I had hoped to do:
var sql = 'SELECT [row],etext,ftext FROM [hcd.hdctext] WHERE (REGEXP_MATCH(etext, esearch = ?) AND REGEXP_MATCH(ftext, fsearch = ?));';
var queryResults;
var resource = {
query: sql,
timeoutMs: 1000,
esearch='r"[^a-zA-z]comfortable"',
fsearch='r"[a-z,A-z]confortable"'
};
queryResults = BigQuery.Jobs.query(resource,projectNumber);
And then have esearch and fsearch filled in with the values (which could be set elsewhere).
That does not work, according to the doc.
Any suggestions on how to get a parameter in an SQL query? (I could not find a setString function...)
Thanks!
Unfortunately, BigQuery doesn't support this type of parameter substitution. It is on our list of features to consider, and I'll bump the priority since it seems like this is a common request.
The only suggestion that I can make in the mean time is that if you are building query strings by hand, you will need to make sure you escape them carefully (which is a non-trivial operation).
I am querying a MS SQL database using Linq and Entity Framework Code First. The requirement is to be able to run a WHERE SomeColumn LIKE '%sometext'clause against the table.
This, on the surface, is a simple requirement that could be accomplished using a simple Linq query like this:
var results = new List<MyTable>();
using(var context = new MyContext())
{
results = context.MyTableQueryable
.Where(x => x.SomeColumn.EndsWith("sometext"))
.ToList();
}
// use results
However, this was not effective in practice. The problem seems to be that the column SomeColumn is not varchar, rather it's a char(31). This means that if a string is saved in the column that is less than 31 characters then there will be spaces added on the end of the string to ensure a length of 31 characters, and that fouls up the .EndsWith() query.
I used SQL Profiler to lookup the exact sql that was generated from the .EndsWith() method. Here is what I found:
--previous query code removed for brevity
WHERE [Extent1].[SomeColumn] LIKE N'%sometext'
So that is interesting. I'm not sure what the N means before '%sometext'. (I'll Google it later.) But I do know that if I take the same query and run it in SSMS without the N like this:
--previous query code removed for brevity
WHERE [Extent1].[SomeColumn] LIKE '%sometext'
Then the query works fine. Is there a way to get Linq and Entity Framework to drop that N from the query?
Please try this...
.Where(x => x.SomeColumn.Trim().EndsWith("sometext"))
Just spoke to my colleague who had a similar issue, see if the following works for you:
[Column(TypeName = "varchar")]
public string SomeColumn
{
get;
set;
}
Apparently setting the type on the column mapping will force the query to recognise it as a VARCHAR, where a string is normally interpreted as an NVARCHAR.
I am building a Search function for a shopping cart site, which queries a SQL Server database. When the user enters "Hula Hoops" in the search box, I want results for all records containing both "Hula" and "Hoop", in any order. Furthermore, I need to search multiple columns (i.e. ProductName, Description, ShortName, MaufacturerName, etc.)
All of these product names should be returned, when searching for "Hula hoop":
Hula hoop
Hoop Hula
The Hoopity of xxhula sticks
(Bonus points if these can be ordered by relevance!)
It sounds like you're really looking for full-text search, especially since you want to weight the words.
In order to use LIKE, you'll have to use multiple expressions (one per word, per column), which means dynamic SQL. I don't know which language you're using, so I can't provide an example, but you'll have to produce a statement that's like this:
For "Hula Hoops":
where (ProductName like '%hula%' or ProductName like '%hoops%')
and (Description like '%hula%' or Description like '%hoops%')
and (ShortName like '%hula%' or ShortName like '%hoops%')
etc.
Unfortunately, that's really the only way to do it. Using Full Text Search would allow you to reduce your criteria to one per column, but you'll still have to specify the columns explicitly.
Since you're using SQL Server, I'm going to hazard a guess that this is a C# question. You'd have to do something like this (assuming you're constructing the SqlCommand or DbCommand object yourself; if you're using an ORM, all bets are off and you probably wouldn't be asking this anyway):
SqlCommand command = new SqlCommand();
int paramCount = 0;
string searchTerms = "Hula Hoops";
string commandPrefix = #"select *
from Products";
StringBuilder whereBuilder = new StringBuilder();
foreach(string term in searchTerms.Split(' '))
{
if(whereBuilder.Length == 0)
{
whereBuilder.Append(" where ");
}
else
{
whereBuilder.Append(" and ");
}
paramCount++;
SqlParameter param = new SqlParameter(string.Format("param{0}",paramCount), "%" + term + "%");
command.Parameters.Add(param);
whereBuilder.AppendFormat("(ProductName like #param{0} or Description like #param{0} or ShortName like #param{0})",paramCount);
}
command.CommandText = commandPrefix + whereBuilder.ToString();
SQL Server Full Text Search should help you out. You will basically create indexes on the columns you want to search. in the where clause of your query you will use the CONTAINS operator and pass it your search input.
you can start HERE or HERE to learn more
You might want to check out SOLR too - if you're going to be doing this type of searching. Super cool.
http://lucene.apache.org/solr/