I am checking login of a user by this repository method,
public bool getLoginStatus(string emailId, string password)
{
var query = from r in taxidb.Registrations
where (r.EmailId == emailId && r.Password==password)
select r;
if (query.Count() != 0)
{
return true;
}
return false;
}
I saw in one of the previous questions !query.Any() would be faster... Which should i use? Any suggestion....
The sql generated will be different between the two calls. You can check by setting your context.Log property to Console.Out or something.
Here's what it will be:
SELECT COUNT(*) AS [value]
FROM [dbo].[Registrations] AS [t0]
WHERE [t0].[EmailId] = #p0 and [t0].Password = #p1
SELECT
(CASE
WHEN EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[Registrations] AS [t0]
WHERE [t0].[EmailId] = #p0 and [t0].Password = #p1
) THEN 1
ELSE 0
END) AS [value]
In this case, I doubt it will make any difference because EmailID is probably a unique index so there can only be 1 result. In another case where count can be > 1, Any would be preferable because the second query allows sql server to short circuit the search since it only needs to find one to prove that any exist.
You could express it quite a bit shorter like this:
return taxidb.Registrations.Any(r => r.EmailId == emailId && r.Password==password);
Related
so i have a table called cars designed like this: ID, Model, Category, Availability.
The categories are standard and luxury.
im trying to write a function that returns either a boolean or an int like this :
function(id)
if category == luxury;
return 1;
else return 0;
i did this select statement but i dont know if i can use it
SELECT (CASE WHEN Category = 'Luxury' THEN 1 ELSE 0 END) AS is_equal
FROM CARS
WHERE ID = 'TM63DTI';
I have to do it in pl/sql. its for a school project and im stuck at this point. I dont have an error with this select statement, i just dont really know how to use it. Maybe suggest an idea of how i can approach this.
PL/SQL means "Oracle", not "MySQL". I suggest you fix tags.
So, if it really is Oracle, then one option might be this:
create or replace function f_category
(par_id in cars.id%type)
return boolean
is
l_is_equal number;
begin
select case when category = 'Luxury' then 1
else 0
end
into l_is_equal
from cars
where id = par_id;
return l_is_equal = 1;
end;
/
Though, it is kind of difficult to use a function that returns Boolean in SQL, so - perhaps you'd also want to consider option that returns a number instead. It is simple to convert previous function to a new version:
create or replace function f_category
(par_id in cars.id%type)
return number
is
l_is_equal number;
begin
select case when category = 'Luxury' then 1
else 0
end
into l_is_equal
from cars
where id = par_id;
return l_is_equal;
end;
/
Now you can use it in SQL as e.g.
select f_category(par_id => 123) from dual;
or
select *
from cars
where f_category(id) = 1;
How can I count the records in a MySQL table in Hibernate? I tried the following HQL, but it does not work.
SELECT COUNT(*) FROM MEMBERS WHERE `username` =:USERNAME OR `email` =:EMAIL
It is used in the following method:
public boolean checkInfos() {
Session newSession = NewHibernateUtil.getSessionFactory().openSession();
int count = (Integer) newSession.createSQLQuery("SELECT COUNT(*) FROM MEMBERS WHERE `username` ='admin' OR `email` ='admin'").uniqueResult();
if (count >= 1) {
return false;
} else {
return true;
}
}
I guess you need that
Query q = newSession.createSQLQuery("SELECT COUNT(*) FROM MEMBERS WHERE username = ? OR email =?");
q.setParameter( 1, "your username");
q.setParameter(2, "your email");
Select count(*) returns a Long, not an Integer.
One more thing: The backticks, which you are using, are not accepted by every database.
By the way, you can use count(*) also in HQL. This means, you can use createQuery instead of createSQLQuery. An advantage of HQL is, it is portable from one database to another, which is not always the case for SQL statements.
You also can achieve this by using criteria also.
private Number getCount(){
Criteria criteria = session.createCriteria(Members.class);
criteria.add(Restrictions.or(Restrictions.eq("username", "admin"), Restrictions.eq("email","admin")));
criteria.setProjection(Projections.rowCount());
return (Number) criteria.list();
}
I have a table with a column that has null values... when I try to query for records where that column IS NULL:
THIS WORKS:
var list = from mt in db.MY_TABLE
where mt.PARENT_KEY == null
select new { mt.NAME };
THIS DOES NOT:
int? id = null;
var list = from mt in db.MY_TABLE
where mt.PARENT_KEY == id
select new { mt.NAME };
Why?
after some more googling, I found the answer:
ref #1
ref #2
int? id = null;
var list = from mt in db.MY_TABLE
where object.Equals(mt.PARENT_KEY, id) //use object.Equals for nullable field
select new { mt.NAME };
This LINQ renders to SQL as follows:
((mt.PARENT_KEY IS NULL) AND (#id IS NULL))
OR ((mt.PARENT_KEY IS NOT NULL) AND (#id IS NOT NULL) AND (mt.PARENT_KEY = #id))
One possibility - if mt.PARENT_KEY is of some other type (e.g. long?) then there will be conversions involved.
It would help if you could show the types involved and the query generated in each case.
EDIT: I think I have an idea...
It could be because SQL and C# have different ideas of what equality means when it comes to null. Try this:
where (mt.PARENT_KEY == id) || (mt.PARENT_KEY == null && id == null)
If this is the case then it's a pretty ugly corner case, but I can understand why it's done that way... if the generated SQL is just using
WHERE PARENT_KEY = #value
then that won't work when value is null - it needs:
WHERE (PARENT_KEY = #value) OR (PARENT_KEY IS NULL AND #value IS NULL)
which is what the latter LINQ query should generate.
Out of interest, why are you selecting with
select new { mt.NAME }
instead of just
select mt.NAME
?) Why would you want a sequence of anonymous types instead of a sequence of strings (or whatever type NAME is?
It's definitely a matter of C# and SQL having different notions of how to compare nulls - the question has been addressed here before:
Compare nullable types in Linq to Sql
I have 2 tables
1. Client
2. Operations
Operations can result in: Credits or Debits ('C' or 'D' in a char field) along with date and ammount fields.
I must calculate the balance for each client's account using linQ... The result should also show balance 0 for clients whom didn't make operations yet
I have the following function with linQ statement, but I know it could be done in a better and quicker, shorter way, right? Which will be?
public static double getBalance(ref ClasesDeDatosDataContext xDC, string SSN,
int xidClient)
{
var cDebits =
from ops in xDC.Operations
where (ops.idClient == xidClient) && (ops.OperationCode == 'D')
select ops.Ammount;
var cCredits =
from ops in xDC.Operations
where (ops.idClient == xidClient) && (ops.OperationCode == 'C')
select ops.Ammount;
return (double)(cCredits.Sum() - cDebits.Sum());
}
Thanks !!!
I don't know if the LINQ-to-SQL engine can handle the expression, but something like this should be possible:
return (
from ops in xDC.Operations
where ops.idClient == xidClient
select ops.operationCode == 'C' ? ops.Amount : -ops.Amount
).Sum(a => a);
Or perhaps:
return (
from ops in xDC.Operations
where ops.idClient == xidClient
select new { Sign = ops.operationCode == 'C' ? 1.0 : -1.0, Amount = ops.Amount }
).Sum(o => o.Sign * o.Amount);
If the collection is empty, the Sum method returns zero, so that takes care of clients without transactions.
Edit:
Corrected spelling in query: Ampont -> Amount
I have a function (called "powersearch", the irony!) that searches for a set of strings across a bunch(~ 5) of fields.
The words come in as one string and are separated by spaces.
Some fields can have exact matches, others should have "contains".
(Snipped for brevety)
//Start with all colors
IQueryable<Color> q = db.Colors;
//Filter by powersearch
if (!string.IsNullOrEmpty(searchBag.PowerSearchKeys)){
foreach (string key in searchBag.SplitSearchKeys(searchBag.PowerSearchKeys)
.Where(k=> !string.IsNullOrEmpty(k))){
//Make a local copy of the var, otherwise it gets overwritten
string myKey = key;
int year;
if (int.TryParse(myKey, out year) && year > 999){
q = q.Where(c => c.Company.Name.Contains(myKey)
|| c.StockCode.Contains(myKey)
|| c.PaintCodes.Any(p => p.Code.Equals(myKey))
|| c.Names.Any(n => n.Label.Contains(myKey))
|| c.Company.CompanyModels.Any(m => m.Model.Name.Contains(myKey))
|| c.UseYears.Any(y => y.Year.Equals(year))
);
}
else{
q = q.Where(c => c.Company.Name.Contains(myKey)
|| c.StockCode.Contains(myKey)
|| c.PaintCodes.Any(p => p.Code.Contains(myKey))
|| c.Names.Any(n => n.Label.Contains(myKey))
|| c.Company.CompanyModels.Any(m => m.Model.Name.Equals(myKey))
);
}
}
}
Because the useYear count is rather large, I tried to check for it as little as possible by outruling all numbers that can never be a number that makes sence in this case. Similar checks are not possible on the other fields since they can pretty much contain any thinkable string.
Currently this query takes about 15 secs for a single, non-year string. That's too much.
Anything I can do to improve this?
--Edit--
Profiler shows me the following info for the part where the string is not a year:
exec sp_reset_connection
Audit login
exec sp_executesql N'
SELECT COUNT(*) AS [value]
FROM [dbo].[CLR] AS [t0]
INNER JOIN [dbo].[CO] AS [t1] ON [t1].[CO_ID] = [t0].[CO_ID]
WHERE
([t1].[LONG_NM] LIKE #p0)
OR ([t0].[EUR_STK_CD] LIKE #p1)
OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[PAINT_CD] AS [t2]
WHERE ([t2].[PAINT_CD] LIKE #p2)
AND ([t2].[CLR_ID] = [t0].[CLR_ID])
AND ([t2].[CUSTOM_ID] = [t0].[CUSTOM_ID])
)
)OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[CLR_NM] AS [t3]
WHERE ([t3].[CLR_NM] LIKE #p3)
AND ([t3].[CLR_ID] = [t0].[CLR_ID])
AND ([t3].[CUSTOM_ID] = [t0].[CUSTOM_ID])
)
) OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[CO_MODL] AS [t4]
INNER JOIN [dbo].[MODL] AS [t5] ON [t5].[MODL_ID] = [t4].[MODL_ID]
WHERE ([t5].[MODL_NM] = #p4)
AND ([t4].[CO_ID] = [t1].[CO_ID])
)
)
',N'#p0 varchar(10),#p1 varchar(10),#p2 varchar(10),#p3 varchar(10),#p4 varchar(8)',#p0='%mercedes%',#p1='%mercedes%',#p2='%mercedes%',#p3='%mercedes%',#p4='mercedes'
(took 3626 msecs)
Audit Logout (3673 msecs)
exec sp_reset_connection (0msecs)
Audit login
exec sp_executesql N'
SELECT TOP (30)
[t0].[CLR_ID] AS [Id],
[t0].[CUSTOM_ID] AS [CustomId],
[t0].[CO_ID] AS [CompanyId],
[t0].[EUR_STK_CD] AS [StockCode],
[t0].[SPCL_USE_CD] AS [UseCode],
[t0].[EFF_IND] AS [EffectIndicator]
FROM [dbo].[CLR] AS [t0]
INNER JOIN [dbo].[CO] AS [t1] ON [t1].[CO_ID] = [t0].[CO_ID]
WHERE
([t1].[LONG_NM] LIKE #p0)
OR ([t0].[EUR_STK_CD] LIKE #p1)
OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[PAINT_CD] AS [t2]
WHERE ([t2].[PAINT_CD] LIKE #p2)
AND ([t2].[CLR_ID] = [t0].[CLR_ID])
AND ([t2].[CUSTOM_ID] = [t0].[CUSTOM_ID])
)
)
OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[CLR_NM] AS [t3]
WHERE ([t3].[CLR_NM] LIKE #p3)
AND ([t3].[CLR_ID] = [t0].[CLR_ID])
AND ([t3].[CUSTOM_ID] = [t0].[CUSTOM_ID])
)
)
OR (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[CO_MODL] AS [t4]
INNER JOIN [dbo].[MODL] AS [t5] ON [t5].[MODL_ID] = [t4].[MODL_ID]
WHERE ([t5].[MODL_NM] = #p4)
AND ([t4].[CO_ID] = [t1].[CO_ID])
)
)'
,N'#p0 varchar(10),#p1 varchar(10),#p2 varchar(10),#p3 varchar(10),#p4 varchar(8)',#p0='%mercedes%',#p1='%mercedes%',#p2='%mercedes%',#p3='%mercedes%',#p4='mercedes'
(took 3368 msecs)
The database structure, sadly, is not under my control. It comes from the US and has to stay in the exact same format for compatibility reasons. Although most of the important fields are indeed indexed, they are indexed in (unnecessary) clustered primary keys. There's verry little I can do about that.
Okay, let's break this down - the test case you're interested in first is a single non-year, so all we've got is this:
q = q.Where(c => c.Company.Name.Contains(myKey)
|| c.StockCode.Contains(myKey)
|| c.PaintCodes.Any(p => p.Code.Contains(myKey))
|| c.Names.Any(n => n.Label.Contains(myKey))
|| c.Company.CompanyModels.Any(m => m.Model.Name.Equals(myKey))
Am I right? If so, what does the SQL look like? How long does it take just to execute the SQL statement in SQL Profiler? What does the profiler say the execution plan looks like? Have you got indexes on all of the appropriate columns?
Use compiled queries.
If you don't, you will lose up to 5-10x times performance, as LINQ-to-SQL will have to generate SQL from query every time you call it.
Things become worse when you use non-constants in LINQ-to-SQL as getting their values is really slow.
This assumes that you already have indexes and sane DB schema.
BTW, I am not kidding about 5-10x part.