Linq with two tables and an excel file - c#

I have a file that where I have rows that need to be inserted into a destination_table. The destination_table is related in the database with another table, we will call it head_table.
I am using a DataTable class to get the data.
I have the following code but I don't get the expected result.
The query returns zero and this must not be so, it must be greater than zero
If someone could guide me a little, thank you very much.
var query =
from file in ta.AsEnumerable()
join head_table in tc.AsEnumerable()
on file["ID"] equals head_table["ID"]
join destination_table in td.AsEnumerable()
on new { ID = file["ID"].ToString().Trim() } equals new { ID = destination_table["ID"].ToString().Trim() }
into gj
from result in gj.DefaultIfEmpty()
select new { line = file, destination_table_key = (result == null ? null : result["ID"]) };
var insertValues = query.Where(a => a.destination_table_key == null);
//It has to return greater than zero and currently I can't get it
if (insertValues.Count() > 0)
{
foreach (var re in insertValues)
{
InsertRow... //Here is the part of the insert
}
}

Related

MVC Linq Invalid length parameter passed to the LEFT or SUBSTRING function

Good day. I have a Linq code that when run, shows this error
Invalid length parameter passed to the LEFT or SUBSTRING function.
But when I try to put all the same values into SQL, it works fine. Is there something wrong with my LINQ code?
THE OUTPUT IN SQL
OUTPUT
CODE
var list = (from R in db.vwEtracs_Receipt
join RI in db.vwEtracs_ReceiptItem on R.objid equals RI.parentid
join IA in db.vwEtracs_IncomeAccount on RI.acctid equals IA.objid
join M in db.vwtbl_Motor
on new { motor_no = R.remarks.Substring(5), operator_id = R.payerId }
equals new { motor_no = M.motor_no, operator_id = M.operator_id } into M_join
from M in M_join.DefaultIfEmpty()
join F in db.tbl_Franchise on R.objid equals F.or_id into F_join
from F in F_join.DefaultIfEmpty()
join B in db.tbl_Make on M.brand_id equals B.id
where
IA.objid == "FTFA00000238" &&
R.voidId == null &&
R.remarks != null
orderby R.txndate descending
select new PayedViewModel
{
application_no = F.application_no,
remarks = R.remarks,
serialno = R.serialno,
payername = R.payername,
payeraddress = R.payeraddress,
motor_no = M.motor_no,
chassis_no = M.chassis_no,
plate_no = M.plate_no,
brand_name = B.Make,
motor_id = M.motor_id,
year = R.txndate.Value.Year.ToString(),
mtop = F.mtop,
franchise_id = F.franchise_id
}
).Distinct();
Usually the error shows in this line, motor_no = R.remarks.Substring(5) because when I change it to 4, the code runs smoothly. I tried manually checking all the data in the db but found nothing suspicious nor anything that will give it negative value.
At this point I don't know what is wrong with my code or db. Thank you.
It may happen because your database have string which it's length less than 5
make sure that all R.remarks.length are more than 5
may be you need to do check or something like this :
R.remarks.Length > 5 ? R.remarks.Substring(5) : R.remarks

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.

When does Entity framework Linq query Hits Sql Databse?

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());

Unable to create a constant value of type while editing User in EF with Linq

While trying to see if a table contains a certain set of values I am getting this error. Below is where the error is being thrown. Does anyone know how to get around this exception and still check my table so I can avoid inserting duplicate rows? Thank you!
var qryDepts = from p in AuthContext.Dept_User_Bridge
where p.UserID == editedUser.UserID
select p;
foreach (var dept in editedUser.DeptIDs)
{
var deptObj = new Dept_User_Bridge { UserID = editedUser.UserID, DeptID = dept };
//exception thrown here
if (!qryDepts.Contains(deptObj))
{
AuthContext.Dept_User_Bridge.Add(new Dept_User_Bridge
{
DeptID = dept,
UserID = editedUser.UserID
});
}
}
One thing is you want to load data into Memory with ToList().
var qryDepts = (from p in AuthContext.Dept_User_Bridge
where p.UserID == editedUser.UserID
select p).ToList();
Then, you could try with Any().
if(!qryDepts.Any(x => x.UserID == deptObj.UserID))
{
...
}

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.

Categories