When does Entity framework Linq query Hits Sql Databse? - c#

i'm new in entity framework.Below is my code,
So in my code i have created object of my db context and then i have a query 'queryForAuthentication' and in that i have used two tables 'conDb.SystemMasters' and joined with conDb.SystemAdminMasters , so will hit twice or how does it manage . i want to know when does entity framework will hit in to database ?
QuizzrEntities conDb = new QuizzrEntities();
List<OnLoginData> lstOnLogoonData = new List<OnLoginData>();
string userpassWordHash = string.Empty;
var queryForAuthentication =from systemObj in conDb.SystemMasters
where systemObj.StaffPin == dminLoginInput.StaffPin
join admin in conDb.SystemAdminMasters on systemObj.SystemId equals admin.SystemID
select new
{
admin.PasswordSalt,
admin.PasswordHash,
systemObj.StaffPin,
admin.UserName,
admin.SystemID
};
if (queryForAuthentication.Count() > 0)
{
CheckStaffPin = true;
var GetUserUsingUsernamePasword = queryForAuthentication.Where(u => u.UserName.ToLower() == AdminLoginInput.UserName.ToLower());
if (GetUserUsingUsernamePasword.ToList().Count == 1)
{
checkuserName = true;
string DBPasswordSalt = queryForAuthentication.ToList()[0].PasswordSalt,
DBPasswordHash = queryForAuthentication.ToList()[0].PasswordHash,
StaffPin = queryForAuthentication.ToList()[0].StaffPin;
userpassWordHash = Common.GetPasswordHash(AdminLoginInput.Password, DBPasswordSalt);
if ((DBPasswordHash == userpassWordHash) && (AdminLoginInput.StaffPin.ToLower() == StaffPin.ToLower()))
{
checkPassword = true;
CheckStaffPin = true;
}
else if (DBPasswordHash == userpassWordHash)
{
checkPassword = true;
}
else if (AdminLoginInput.StaffPin.ToLower() == StaffPin.ToLower())
{
CheckStaffPin = true;
}
}
}
So in my code i have created object of my db context and then i have a query 'queryForAuthentication' and in that i have used two tables 'conDb.SystemMasters' and joined with conDb.SystemAdminMasters , so will hit twice or how does it manage .
i want to know when does entity framework will hit in to database ?

It's hits the database whenever you fire a query. And query will be fired whenever you perform ToList, First, FirstOrDefault etc. operation. Till then it only builds the query.

try Code
QuizzrEntities conDb = new QuizzrEntities();
List<OnLoginData> lstOnLogoonData = new List<OnLoginData>();
string userpassWordHash = string.Empty;
var queryForAuthentication =(from systemObj in conDb.SystemMasters
where systemObj.StaffPin == dminLoginInput.StaffPin
join admin in conDb.SystemAdminMasters on systemObj.SystemId equals admin.SystemID
select new
{
PasswordSalt= admin.PasswordSalt,
PasswordHash= admin.PasswordHash,
StaffPin= systemObj.StaffPin,
UserName= admin.UserName,
SystemID = admin.SystemID
}).FirstOrDefault();
If(queryForAuthentication !=null)
{
-----------------
-----------------
*****Your Code*******
}

In entity framework also work with sql query based. If you are disconnected using .ToList() then only the record taken from local otherwise it's works as DBQuery. if you check the result view in debug view it's Execute the Query and Return the data.
If you are processing the data is discontinued from the base it's executed finally where you want the result.
You processing data locally then you can disconnect the connection between linq and sql using call .ToList(). it's Processing only one time the Object weight is high more than query.

var queryForAuthentication =from systemObj in conDb.SystemMasters
where systemObj.StaffPin == dminLoginInput.StaffPin
join admin in conDb.SystemAdminMasters on systemObj.SystemId equals admin.SystemID
select new
{
admin.PasswordSalt,
admin.PasswordHash,
systemObj.StaffPin,
admin.UserName,
admin.SystemID
}.ToList() ; // It will fetch the data
//Check from inmemory collection
if (queryForAuthentication.Count > 0)
//As you already have the data in memory this filter applied against inmemory collection not against database.
var GetUserUsingUsernamePasword = queryForAuthentication
.Where(u =>u.UserName.ToLower() == AdminLoginInput.UserName.ToLower());

Related

Update IQueryable result before using as join in next query

I need to use Linq to Entity Framework to query a LOCATION table to get the record of the location code with the MAX effective date, then use that result as a join in the next query.
I BELIEVE I need to do convert before the IQueryable is used, because I have that last clause in the second query where I want to exclude records where the FLOOR code is in the excludedSchools list. That excludedSchools list will have the newLocationCode in it.
So, I need to update the values in the IQueryable result before I use it. Can I do this? Here is my code:
using (var db = new TheContext())
{
IQueryable<LocationTable> locatinWithMaxEffDate =
(from lc in db.LocationTable
where lc.EFF_STATUS == "A" && lc.EFFDT <= DateTime.Now
group lc by lc.LOCATION into g
select g.OrderByDescending(x => x.EFFDT).FirstOrDefault()
);
foreach (var location in locatinWithMaxEffDate.ToList())
{
string newLocationCode;
if(codeMappingDictionary.TryGetValue(location.FLOOR, out newLocationCode))
{
// how do I update locatinWithMaxEffDate FLOOR value
// with newLocationCode so it works in the query below?
location.FLOOR = newLocationCode;
}
}
var query =
(from fim in db.PS_PPS_FIM_EE_DATA
join mloc in locatinWithMaxEffDate on fim.LOCATION equals mloc.LOCATION
where
fim.EMPL_STATUS == PsPpsFimEeData.EmployeeStatusValues.Active
&& fim.AUTO_UPDATE == PsPpsFimEeData.AutoUpdateValues.Enabled
&& includeJobCodes.Contains(fim.JOBCODE)
&& !excludedSchools.Contains(mloc.FLOOR)
select new PpsAdministratorResult
{
SchoolId = mloc.FLOOR,
Login = fim.OPRID,
EmployeeId = fim.EMPLID,
}
With the code above, the locatinWithMaxEffDate does not have the updated FLOOR values. I can see why this is, but can't seem to fix it.
So far, I have tried introducing another list to ADD() the new location record to, then casting that as an IQueryable, but I get an error about primitive vs concrete types.
I decided to make things easier on myself. Since both sets of data are very small (fewer than 1000 records each) I call take the entire set of data as an annonymous type:
using (var db = new TheContext())
{
IQueryable<LocationTable> locatinWithMaxEffDate =
(from lc in db.LocationTable
where lc.EFF_STATUS == "A" && lc.EFFDT <= DateTime.Now
group lc by lc.LOCATION into g
select g.OrderByDescending(x => x.EFFDT).FirstOrDefault()
);
var query =
(from fim in db.PS_PPS_FIM_EE_DATA
join mloc in locatinWithMaxEffDate on fim.LOCATION equals mloc.LOCATION
where
fim.EMPL_STATUS == PsPpsFimEeData.EmployeeStatusValues.Active
&& fim.AUTO_UPDATE == PsPpsFimEeData.AutoUpdateValues.Enabled
&& includeJobCodes.Contains(fim.JOBCODE)
select new PpsAdministratorResult
{
SchoolId = mloc.FLOOR,
Login = fim.OPRID,
EmployeeId = fim.EMPLID,
}
}
Then, just work with the two objects:
List<PpsAdministratorResult> administratorList = new List<PpsAdministratorResult>();
foreach (var location in query.ToList())
{
string newLocationCode;
if(schoolCodeMappings.TryGetValue(location.SchoolId, out newLocationCode)) // && newLocationCode.Contains(location.LOCATION))
{
location.SchoolId = newLocationCode;
}
if( !excludedSchools.Contains(location.SchoolId) )
{
administratorList.Add(location);
}
}
Now, I have the list I want.

Subquery using LINQ to SQL

I am using LINQ to SQL in my C# tutorial project but I have basic knowledge of it.
I made a SQL query like this:
SELECT ID,HeroName,HeroRarity,Initiative,Attack,Attack1
FROM CharactersName
WHERE ID IN(
SELECT HeroID
FROM Hero_Group
WHERE GroupID=1
)
(Hero_Group) is a table to deal with a many-to-many relation between (CharactersName) table and another table named (Groups) where a character can be in more than one group.
I tried to write it in LINQ like this:
void FilterGroup()
{
HDAEntities db = new HDAEntities();
var query = from obj in db.CharactersNames
where obj.ID == from obj2 in db.Hero_Group
where obj2.GroupID == comboBox1.SelectedIndex
select new
{
obj2.GroupID
}
select new
{
obj.ID,
obj.HeroName,
obj.HeroRarity,
obj.Initiative,
obj.Attack,
obj.Attack1
};
}
But of course this is gibberish.
Can someone help me, please ? (be informed that I have little knowledge of LINQ to SQL)
~TIA~
You can do it like this:
void FilterGroup()
{
HDAEntities db = new HDAEntities();
var subQuery = db.Hero_Group.Where(h => h.GroupID == comboBox1.selectedIndex)
.Select(h => h.GroupID);
var query = from obj in db.CharactersNames
where subQuery.Contains(obj.ID)
select new
{
obj.ID,
obj.HeroName,
obj.HeroRarity,
obj.Initiative,
obj.Attack,
obj.Attack1
};
var result = query.ToList(); // this is where your query and subquery are evaluated and sent to the database
db.Dispose();
db = null;
}
Note that the subQuery is not evaluated until you call ToList(). You also need to dispose the object (or try the using statement to create the HDAEntities object). Also, make sure you don't dispose the db before evaluating the query (calling ToList after Dispose will throw an exception).
var query = from obj in db.CharactersNames
where (from obj2 in db.Hero_Group
where obj2.GroupID == comboBox1.SelectedIndex
select new {obj2.GroupID}).Contains(obj.ID)
select new
{
obj.ID,
obj.HeroName,
obj.HeroRarity,
obj.Initiative,
obj.Attack,
obj.Attack1
};
var query = from obj in db.CharactersNames
where (from obj2 in db.Hero_Group
where obj2.GroupID == comboBox1.SelectedIndex
select new {obj2.GroupID}).Contains(obj.ID)
select new
{
obj.ID,
obj.HeroName,
obj.HeroRarity,
obj.Initiative,
obj.Attack,
obj.Attack1
};

Entity Query in Query, is it possible

I'm not really sure how to ask this question. I need to create an object, I believe it is called a projection, that has the result of one query, plus from that need to query another table and get that object into the projection.
This is a C# WCF Service for a Website we are building with HTML5, JS, and PhoneGap.
EDIT: Getting an error on the ToList (see code) - "The method or operation is not implemented."
EDIT3: changed the Entity Object company_deployed_files to IQueryable AND removed the FirstOrDefault caused a new/different exception Message = "The 'Distinct' operation cannot be applied to the collection ResultType of the specified argument.\r\nParameter name: argument"
Background: This is a kind of messed up Entity Model as it was developed for Postgresql, and I don't have access to any tools to update the model except by hand. Plus some design issues with the database does not allow for great model even if we did. In other words my two tables don't have key constrains(in the entity model) to perform a join in the entity model - unless someone shows me how - that honestly might be the best solution - but would need some help with that.
But getting the below code to work would be a great solution.
public List<FileIDResult> GetAllFileIDFromDeviceAndGroup ( int deviceID, int groupID)
{
List<FileIDResult> returnList = null;
using (var db = new PgContext())
{
IQueryable<FileIDResult> query = null;
if (deviceID > 0)
{
var queryForID =
from b in db.device_files
where b.device_id == deviceID
select new FileIDResult
{
file_id = b.file_id,
file_description = b.file_description,
company_deployed_files = (from o in db.company_deployed_files
where o.file_id == b.file_id
select o).FirstOrDefault(),
IsDeviceFile = true
};
if (query == null)
{
query = queryForID;
}
else
{
// query should always be null here
}
}
if (groupID > 0)
{
var queryForfileID =
from b in db.group_files
where b.group_id == groupID
select new FileIDResult
{
file_id = b.file_id,
file_description = b.file_description,
company_deployed_files = (from o in db.company_deployed_files
where o.file_id == b.file_id
select o).FirstOrDefault(),
IsDeviceFile = false
};
if (query != null)
{
// query may or may not be null here
query = query.Union(queryForfileID);
}
else
{
// query may or may not be null here
query = queryForfileID;
}
}
//This query.ToList(); is failing - "The method or operation is not implemented."
returnList = query.ToList ();
}
return returnList;
}
Edit 2
The ToList is throwing an exception.
I'm 98% sure it is the lines: company_deployed_files = (from o in db.company_deployed_files where o.file_id == b.file_id select o).FirstOrDefault()
End Edit 2

How to Fetch Data from database using Entity Framework 6

I have build a query to return data from two tables in which they are joined by inner join. Although, as the query seems fine, i am getting error message when i try to access the selected field names from the query. How do i use .SingleOrDefault() function in this query. Can anybody help me how should i proceed.
private void FindByPincode(int iPincode)
{
using (ABCEntities ctx = new ABCEntities())
{
var query = from c in ctx.Cities
join s in ctx.States
on c.StateId equals s.StateId
where c.Pincode == iPincode
select new {
s.StateName,
c.CityName,
c.Area};
// var query = ctx.Cities.AsNoTracking().SingleOrDefault(_city => _city.Pincode == iPincode);
if (query != null)
{
cboState.SelectedItem.Text =query.State; //Getting error "Could not found"
cboCity.SelectedItem.Text = query.CityName; //Getting error "Could not found"
txtArea.Text = query.Area; //Getting error "Could not found"
}
}
}
Thanks in advance.
Try this:
using (ABCEntities ctx = new ABCEntities())
{
var query = (from c in ctx.Cities
join s in ctx.States
on c.StateId equals s.StateId
where c.Pincode == iPincode
select new {
s.StateName,
c.CityName,
c.Area}).FirstOrDefault();
if (query != null)
{
cboState.SelectedItem.Text =query.State;
cboCity.SelectedItem.Text = query.CityName;
txtArea.Text = query.Area;
}
}
can it be that you are selecting a field named StateName, and then acessing State.
cboState.SelectedItem.Text =query.State;
cboState.SelectedItem.Text =query.StateName;
Please provide more details on the error and the class structure of your code
Here's how a similar situation worked for me:
using (ABCEntities ctx = new ABCEntities())
{
var query = (from c in ctx.Cities
join s in ctx.States
on c.StateId equals s.StateId
where c.Pincode == iPincode
select new {
s.StateName,
c.CityName,
c.Area}).Single();
if (query.Any())
{
cboState.SelectedItem.Text =query.State;
cboCity.SelectedItem.Text = query.CityName;
txtArea.Text = query.Area;
}
}
Notice that i used query.Any() up there, that is because query != null will always return true. However any() checks if a query has returned 1 or more records, if yes Any() returns true and if a query returns no records then Any() returns false.

Role description does not get updated

I am getting the role being created but the description does not get updated.
I have tried in two ways:
First:
Roles.CreateRole(model.RoleName);
using (tgpwebgedEntities context = new tgpwebgedEntities())
{
var query = from r in context.aspnet_Roles where r.RoleName == r.RoleName select r;
var obj = query.First();
obj.Description = model.Description;
context.SaveChanges();
}
Second:
using(tgpwebgedEntities context = new tgpwebgedEntities()) {
var obj = context.aspnet_Roles.Single(r => r.RoleName == roleModel.RoleName);
obj.Description = roleModel.Description;
context.SaveChanges();
}
The curious thing is that this second way is the way I am using when the user is editing an aready created role using another action and works fine.
This first is used in a method that created the role and update its description since there is no support for description in .NET.
The problem is with your query statement,
var query = from r in context.aspnet_Roles where r.RoleName == r.RoleName select r;
"r.RoleName == r.RoleName" which will always be true and returns all entries. The query should be something similar to what you have in the second query
r => r.RoleName == roleModel.RoleName

Categories