I have query1 which leads to low-level controller and query which leads to high level controller. I am trying to get my method, to read the query1 first then the query. When I login, it always lead to query - low level page, instead of high-level page. Please advice, if possible.
public UserDetail full(string username, string password)
{
var query1 = from s in db.Subscriptions
join u in db.UserDetails on s.sUID equals u.uID
where s.sPrice_ExpiryDate >= DateTime.Now &&
s.sPID.Value == 163 &&
s.sWIC_All.Value == true &&
u.uUsername == username &&
u.uPassword == password
select u;
var query = from s in db.Subscriptions
join u in db.UserDetails on s.sUID equals u.uID
where s.sTrialExpiryDate >= DateTime.Now &&
s.sPID.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select u;
if (query1 != null)
{
return query1.FirstOrDefault();
}
return query.FirstOrDefault();
}
Thank you.
query1 will never be null. It is a query.
var result1 = query1.FirstOrDefault();
if (result1 != null)
{
return result1;
}
return query.FirstOrDefault();
Or, in shorthand:
return query1.FirstOrDefault() ?? query.FirstOrDefault();
Related
I am having following query which pulls data from a table with records that should not be present in another table.
The query is working perfectly but it is taking too much time & performance is affected tremendously.
What changes can i make to this query to get better performance or should i be doing this in another way?
var data = (from A in ctx.tblMachine
where
A.CompanyId == companyId &&
A.InOutDate >= tempDt &&
A.InOutDate <= toDate &&
!(from B in ctx.tblEntry
where
B.CompanyId == companyId &&
A.EmployeeId == B.EmployeeId &&
A.InOutDate == B.EntryDate &&
B.EntryMethod == "M"
select new
{
B.EmployeeId
}).Contains(new { EmployeeId = A.EmployeeId })
orderby
A.EmployeeId, A.InOutDate select new
{
A.EmployeeId,
A.InOutDate,
A.InOutFlag,
A.InOutTime
}).ToList();
You can try with join also instead of inner query... You can use like this make change as per your need..
var data = (from A in ctx.tblMachine
join B in ctx.tblEntry on A.EmployeeId == B.EmployeeId &&
A.InOutDate == B.EntryDate &&
B.CompanyId == companyId &&
B.EntryMethod == "M"
where
A.CompanyId == companyId &&
A.InOutDate >= tempDt &&
A.InOutDate <= toDate &&
!(B.EmployeeId).Contains(new { EmployeeId = A.EmployeeId })
orderby
A.EmployeeId, A.InOutDate
select new
{
A.EmployeeId,
A.InOutDate,
A.InOutFlag,
A.InOutTime
}).ToList();
I have a LINQ query to populate an object (which is then the datasource for a grid) with a few joins.
I want the query to be dynamic so it retrieves rows based on parameters passed, but so far it doesn't work as soon as the StatusID is passed in - it brings back all instances (as if a cartesion product is happening)
_viewfetch.POMastStatusID will either be -1 or a value of 1 or above.
QUERY:
var queryforobject = from p in db.POMasts.AsNoTracking()
join pr in db.Profiles.AsNoTracking() on p.ProfileID equals pr.ID
join c in db.CurrencyTypes.AsNoTracking() on p.CurrencyTypeID equals c.ID
join w in db.WHMasts.AsNoTracking() on p.WarehouseID equals w.ID
join t in db.TermCodeTypes.AsNoTracking() on p.TermCodeTypeID equals t.ID
join s in db.POMastStatusTypes.AsNoTracking() on p.StatusID equals s.ID
//Ensure that these are dynamic
where _viewfetch.VendMastID == -1 || p.VendorID == _viewfetch.VendMastID &&
_viewfetch.POMastStatusID == -1 || p.StatusID == _viewfetch.POMastStatusID
orderby p.ID
//Put the query results into the bespoke object
select new POMastObject { ID = p.ID,
OrderNo = p.OrderNo,
RaisedDate = p.RaisedDate,
RaisedBy = pr.Name,
Currency = c.Description,
Warehouse = w.Description,
Terms = t.Description,
LastEditedBy = p.LastEditedBy,
LastEditedDate = p.LastEditedDate,
Status = s.Name };
if (queryforobject.Count() > 0)
_dataobject = queryforobject.ToList();
Does anyone have any suggestions?
Your query is fine, it's just missing parentheses around the two parts of the && operator:
where (_viewfetch.VendMastID == -1 || p.VendorID == _viewfetch.VendMastID) &&
(_viewfetch.POMastStatusID == -1 || p.StatusID == _viewfetch.POMastStatusID)
Since && has higher precedence than ||, your query effectively evaluates with the two conditions in the middle AND-ed together, like this:
_viewfetch.VendMastID == -1 || (p.VendorID == _viewfetch.VendMastID && _viewfetch.POMastStatusID == -1) || p.StatusID == _viewfetch.POMastStatusID
This is not the logic that you are looking for, because when VendMastID is -1 you get all rows.
I have a fairly complex query written in LINQ which queries my database. I have made sure that I am only pulling back the relevant columns from each entity, so the query is as slim as it can be, and therefore the object which LINQ populates does not contain any unnecessary columns either.
If I run the LINQ query's resulting SQL against the DB directly, the SQL runs in about 4 seconds. However, doing this from my LINQ query takes about 25 seconds. The majority of this 25 seconds is taken up by the returned DB data being written into objects.
Are there any useful tricks which will help LINQ/Entity Framework out when performing this part of the operation?
Edit:
The long delay occurs when I call the ToList() method in the query below:
var q1 = from u in etc.Users
where (u.flags & (int)UserFlags.Student) == (int)UserFlags.Student
&& (ariStudents.Contains(u.id) || ariStudents.Count == 0)
&& (from ua in etc.UserAssociations where ua.datasetId == datasetId && ua.userId == u.id && ua.type == (int)UserAssocTypes.EnrolActive select ua).Any()
orderby u.id
select new ElightsRaw2
{
Student = new ElrStudent{StudentId = u.id},
StudentData = (
from sd in etc.StudentDatas
where sd.userId == u.id
&& sd.datasetId == datasetId
select new ElrStudentData { attP = sd.attP, attA = sd.attA, attL = sd.attL }
).FirstOrDefault(),
ElightOverall = (
from els in etc.eLightsStudents
where els.datasetId == datasetId
&& els.userId == u.id
select els
).FirstOrDefault(),
Groups = (
// get all courses and groups for user
from c in etc.Cours
join g in etc.Groups on c.id equals g.courseId
join ua in etc.UserAssociations on g.id equals ua.fkId
where ua.datasetId == datasetId
&& ua.userId == u.id
&& ua.type == (int)UserAssocTypes.EnrolActive
&& (ua.flags & (int)UserAssociationFlags.AssociationDeleted) == 0
&& (c.flags & (int)CourseFlags.Deleted) == 0
select new ElrGroupHolder
{
CourseName = c.name,
GroupName = g.name,
Breakdown = new ElrGroupHolderBreakdown
{
UnitsBelowScoreThresh1 = (
from uus in etc.UserUnitScores
join un in etc.Units on uus.unitId equals un.id
join cu in etc.CourseUnits on un.id equals cu.unitId
where uus.userId == u.id
&& (un.flags & (int)UnitFlags.Deleted) == 0
&& (cu.flags & (int)CourseUnitFlags.NotStarted) == 0
&& cu.courseId == c.id
&& (uus.performance > -1 && uus.performance <= amberThresh)
&& !(from exc in etc.UserAssociations where exc.userId == u.id && exc.fkId == un.id && exc.type == (int)UserAssocTypes.ExcludedUnit select exc).Any() // not excluded from unit
select uus
).Count(),
UnitsBelowScoreThresh2 = (
from uus in etc.UserUnitScores
join un in etc.Units on uus.unitId equals un.id
join cu in etc.CourseUnits on un.id equals cu.unitId
where uus.userId == u.id
&& (un.flags & (int)UnitFlags.Deleted) == 0
&& (cu.flags & (int)CourseUnitFlags.NotStarted) == 0
&& cu.courseId == c.id
&& (uus.performance > -1 && uus.performance <= redThresh)
&& !(from exc in etc.UserAssociations where exc.userId == u.id && exc.fkId == un.id && exc.type == (int)UserAssocTypes.ExcludedUnit select exc).Any() // not excluded from unit
select uus
).Count(),
CfcCount = (
from cfc in etc.CFCs
where cfc.datasetId == datasetId
&& cfc.studentId == u.id
&& cfc.dt > dCfcCutoff
&& cfc.type == (int)CfcTypes.Concern
&& (cfc.flags & (int)CfcFlags.Deleted) == 0
&& (
// only include attendance and behaviour CFCs
(cfc.flags & (int)CfcFlags.Attendance) == (int)CfcFlags.Attendance
|| (cfc.flags & (int)CfcFlags.Behaviour) == (int)CfcFlags.Behaviour
)
select cfc
).Count(),
SrsScores = (
from srs in etc.SRScores
join sr in etc.SubReviews on srs.srId equals sr.id
where sr.datasetId == datasetId
&& (sr.flags & (int)SrFlags.Deleted) == 0
&& (srs.flags & (int)SrsFlags.Deleted) == 0
&& sr.dt > dCfcCutoff
&& sr.userId == u.id
&& sr.courseId == c.id
select new ElrSrScore
{
attainment = srs.attainment,
attitude = srs.attitude,
motivation = srs.motivation,
studyskill = srs.studyskill
}
).ToList(),
ElightEnrolment = (
from ele in etc.eLightsEnrolments
where ele.datasetId == datasetId
&& ele.groupId == g.id
&& ele.userId == u.id
select ele
).FirstOrDefault(),
},
CourseAttendance = (
from a in etc.Attendances
where a.studentId == u.id
&& a.courseId == c.id
&& a.weekNumberId == null
&& a.datasetId == datasetId
select a
).FirstOrDefault()
}
).ToList(),
};
return q1.ToList();
Yes! I ran into something similar myself not to long ago. What I came up with is using the AsParallel() function within LINQ ... however this comes with a few caveats.
You will be running things in parallel - obvious but if your trying to do things in a non thread safe manner there could be issues
This will only be useful in certain cases - the way I got the most use out of it was when I was converting a lot of database rows into C# objects and doing it repetitively ... think foreach,for,while loops that don't have any decision logic in them but just a straight database row to C# class kind of conversion
It really only makes sense for "large" amounts of data - You're going to have to play around with this and see what the timing difference is but if you are just converting a handful of rows, the overhead for AsParallel() will actually cost you more time, not save you any.
Here is some more reading on AsParallel(), hope this helps!
https://msdn.microsoft.com/en-us/library/vstudio/dd413237%28v=vs.100%29.aspx - AsParallel Method
https://msdn.microsoft.com/en-us/library/dd997425%28v=vs.110%29.aspx - Intro to parallel queries
http://www.dotnetperls.com/asparallel - Good basic walkthrough of AsParallel
I am trying construct a linq method where I can validate two parameters using join and where clauses, but currently I am getting an compiling error - Cannot use local variable 'query' before it is declared -- error.
public bool Validate(string username, string password)
{
var query = from t in db.Trial_Try
join u in db.UserDetails on t.tUID equals u.uID
where t.tExpiryDate >= DateTime.Now &&
t.tPublication.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select query.FirstOrDefault();
}
Thank you for your time and help.
Should be
var query = (from t in db.Trial_Try
join u in db.UserDetails on t.tUID equals u.uID
where t.tExpiryDate >= DateTime.Now &&
t.tPublication.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select t) .FirstOrDefault();
Or u if you wan't those values
Basically you are trying to use query in your select clause, which is not what it is expecting.
var query = from t in db.Trial_Try
join u in db.UserDetails on t.tUID equals u.uID
where t.tExpiryDate >= DateTime.Now &&
t.tPublication.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select t.FirstOrDefault();
public bool Validate(string username, string password)
{
var query = from t in db.Trial_Try
join u in db.UserDetails on t.tUID equals u.uID
where t.tExpiryDate >= DateTime.Now &&
t.tPublication.Value == 163 &&
u.uUsername == username &&
u.uPassword == password
select u;
// "execute" the query
return query.FirstOrDefault() != null;
}
I posted this code snippet over at Stack Exchange's Code Review (beta) in order to obtain some feedback on how best to refactor a multi-part LINQ query.
Being relatively new to LINQ, I'm not really sure where to begin with this query.
If anybody could give me any advice on combining a few of the LINQ queries within the method, I'd appreciate it; especially the 'exclude' IQueryable collections into the main query (see comments).
The query is not particularly performant at the moment and any advice you could give in order to improve its performance from a code perspective would be appreciated.
The comments received on Code Review were more architectural, however I'm not currently in a position where I can move anything to the database at this time.
I appreciate it's a large method, but I've posted the whole lot to give context.
Thanks in advance for any advice you're able to give.
The Method
/// Get templates by username and company
public List<BrowsingSessionItemModel> GetItemBrowsingSessionItems(
int companyId,
string userName,
Boolean hidePendingDeletions,
Boolean hideWithAppointmentsPending,
Boolean hideWithCallBacksPending,
int viewMode,
string searchString,
List<int?> requiredStatuses,
List<int?> requiredSources,
string OrderBy,
BrowsingSessionLeadCustomField fieldFilter)
{
try
{
IQueryable<Lead> exclude1;
IQueryable<Lead> exclude2;
IQueryable<Lead> exclude3;
//To prepare call backs pending
if (hideWithCallBacksPending == true)
{
exclude1 = (from l1 in db.Leads
where (l1.Company_ID == companyId)
from l2 // Hiding Pending Call Backs
in db.Tasks
.Where(o => (o.IsCompleted ?? false == false)
&& (o.TaskType_ID == (int)RecordEnums.TaskType.PhoneCall)
&& (o.Type_ID == (int)RecordEnums.RecordType.Lead)
&& (o.Item_ID == l1.Lead_ID)
&& (o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1))
)
select l1);
}
else
{
exclude1 = (from l1 in db.Leads
where (0 == 1)
select l1);
}
//To prepare appointments backs pending
if (hideWithAppointmentsPending == true)
{
exclude2 = (from a1 in db.Leads
where (a1.Company_ID == companyId)
from a2 // Hiding Pending Appointments
in db.Tasks
.Where(o => (o.IsCompleted ?? false == false)
&& (o.TaskType_ID == (int)RecordEnums.TaskType.Appointment)
&& (o.Type_ID == (int)RecordEnums.RecordType.Lead)
&& (o.Item_ID == a1.Lead_ID)
&& (o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1))
)
select a1);
}
else
{
exclude2 = (from a1 in db.Leads
where (0 == 1)
select a1);
}
//To prepare deletions
if (hidePendingDeletions == true)
{
exclude3 = (from d1 in db.Leads
where (d1.Company_ID == companyId)
from d2 // Hiding Pending Deletions
in db.LeadDeletions
.Where(o => (o.LeadId == d1.Lead_ID))
select d1);
}
else
{
exclude3 = (from d1 in db.Leads
where (0 == 1)
select d1);
}
// MAIN QUERY <--
IQueryable<Lead> list = (from t1 in db.Leads
from t2
in db.LeadSubOwners
.Where(o => t1.Lead_ID == o.LeadId && o.Expiry >= DateTime.Now)
.DefaultIfEmpty()
where (t1.Company_ID == companyId)
where ((t2.Username == userName) && (viewMode == 1)) || ((t1.Owner == userName) && (viewMode == 1)) || ((viewMode == 2)) // Either owned by the user or mode 2 (view all)
select t1).Except(exclude1).Except(exclude2).Except(exclude3);
// Filter sources and statuses seperately
if (requiredStatuses.Count > 0)
{
list = (from t1 in list
where (requiredStatuses.Contains(t1.LeadStatus_ID))
select t1);
}
if (requiredSources.Count > 0)
{
list = (from t1 in list
where (requiredSources.Contains(t1.LeadSource_ID))
select t1);
}
// Do custom field filter here
if (fieldFilter != null)
{
string stringIntegerValue = Convert.ToString(fieldFilter.IntegerValue);
switch (fieldFilter.FieldTypeId)
{
case 1:
list = (from t1 in list
from t2
in db.CompanyLeadCustomFieldValues
.Where(o => t1.Lead_ID == o.Lead_ID && fieldFilter.TextValue == o.LeadCustomFieldValue_Value)
select t1);
break;
case 2:
list = (from t1 in list
from t2
in db.CompanyLeadCustomFieldValues
.Where(o => t1.Lead_ID == o.Lead_ID && stringIntegerValue == o.LeadCustomFieldValue_Value)
select t1);
break;
default:
break;
}
}
List<Lead> itemsSorted; // Sort here
if (!String.IsNullOrEmpty(OrderBy))
{
itemsSorted = list.OrderBy(OrderBy).ToList();
}
else
{
itemsSorted = list.ToList();
}
var items = itemsSorted.Select((x, index) => new BrowsingSessionItemModel
{
Id = x.Lead_ID,
Index = index + 1
});
return items.ToList();
}
catch (Exception ex)
{
logger.Info(ex.Message.ToString());
return new List<BrowsingSessionItemModel>();
}
}
I don't understand why this:
false == false
And that:
where (0 == 1)
Then for excludes 1 and 2:
//To prepare call backs pending
var phoneCallTypeId = (int) RecordEnums.TaskType.PhoneCall;
var exclude1 = GetExclude(hideWithCallBacksPending, companyId, phoneCallTypeId);
//To prepare appointments backs pending
var appointmentTypeId = (int) RecordEnums.TaskType.Appointment;
var exclude2 = GetExclude(hideWithCallBacksPending, companyId, appointmentTypeId);
using the following GetExclude method:
private object GetExclude(bool hideWithCallBacksPending, int companyId, int typeId)
{
return hideWithCallBacksPending
? (from l1 in db.Leads
where (l1.Company_ID == companyId)
from l2
// Hiding Pending Call Backs
in
db.Tasks.Where(
o =>
(o.IsCompleted ?? false) &&
(o.TaskType_ID == typeId) &&
(o.Type_ID == (int) RecordEnums.RecordType.Lead) &&
(o.Item_ID == l1.Lead_ID) &&
(o.Due_Date > EntityFunctions.AddDays(DateTime.Now, -1)))
select l1)
: (from l1 in db.Leads where (0 == 1) select l1);
}
Exclude3:
//To prepare deletions
var exclude3 = hidePendingDeletions
? (from d1 in db.Leads
where (d1.Company_ID == companyId)
from d2
// Hiding Pending Deletions
in db.LeadDeletions.Where(o => (o.LeadId == d1.Lead_ID))
select d1)
: (from d1 in db.Leads where (0 == 1) select d1);
Excludes 1 and 2 can be called inline as they are short:
// Either owned by the user or mode 2 (view all)
...select t1)
.Except(GetExclude(hideWithCallBacksPending, companyId, phoneCallTypeId))
.Except(GetExclude(hideWithCallBacksPending, companyId, appointmentTypeId))
.Except(exclude3);