syntax error in simple LINQ statement - asp.net-mvc

I am developing MVC app and I am using the LINQ in controller.
I am trying to get one rechord with below query, but its giving an error...
Approval oAP = new Approval();
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
Is there any wrong syntax ?
Got the answer
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount)).FirstOrDefault();

Change this
e.ApprovedBy.Id = loggedEmployee.Id
For
e.ApprovedBy.Id == loggedEmployee.Id
You're comparing not assigning values.
Also you may add this
oAP = db.Approvals.Where(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount)).FirstOrDefault();
Because i'm assuming that you want to return only one

Some remarks:
You should be able to drop the Where:
oAP = db.Approvals.FirstOrDefault(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
Personally, I try to avoid the First and FirstOrDefault functions, because if you know there is only one record and if you want to enforce this, you can use SingleOrDefault:
oAP = db.Approvals.SingleOrDefault(e => (e.ApprovedBy.Id == loggedEmployee.Id) && (e.ReviewNo == oPaymentAdvice.ReviewCount));
If you know there will always be (more than) one record, you can drop the 'OrDefault' part and use First() or Single().

Related

Entity Framework query exception when looking for an entity contained in a collection

I'm running the query below to obtain all the events (as a registered student) I'm attending on a specific day and getting an error that says
System.NotSupportedException: Unable to create a constant value of type 'YogaBandy.Models.Profile.YogaProfile'. Only primitive types or enumeration types are supported in this context.
Here is the query I'm using to get all events I'm regsitered for on a specific day.
// my profile
var yogaProfile = dbContext.YogaProfiles.Where(i => i.ApplicationUserId == userId).First();
// events I'm registered for on a specific day
var eventsNew = dbContext.YogaSpaceEvents.Where(
i => i.EventDateTime.Day == date.Day
&& i.EventStatus == YogaSpaceEventStatus.Active
&& i.RegisteredStudentsNew.Contains(yogaProfile)).ToList();
I think it might have something to do with part, but not sure
&& i.RegisteredStudentsNew.Contains(yogaProfile)
FYI - my RegisteredStudentsNew looks like this in the 'YogaSpaceEvents' entity
public virtual ICollection<YogaProfile> RegisteredStudentsNew { get; set; }
and when I add a newly regsitered student I add him/her like this
spaceEvent.RegisteredStudentsNew.Add(yogaProfile);
dbContext.SaveChanges();
Try to move your YogaProfiles.Where(i => i.ApplicationUserId == userId) inside Include statement.
Example:
var eventsNew = dbContext.YogaSpaceEvents
.Include(p=>p.RegisteredStudentsNew.Where(rp => rp.ApplicationUserId == userId))
.Where( i => i.EventDateTime.Day == date.Day
&& i.EventStatus == YogaSpaceEventStatus.Active)
.ToList();
OR
use Any in your where clause
var eventsNew = dbContext.YogaSpaceEvents
.Include(p=>p.RegisteredStudentsNew)
.Where(i => i.EventDateTime.Day == date.Day
&& i.EventStatus == YogaSpaceEventStatus.Active
&& i.RegisteredStudentsNew.Any(rp => rp.ApplicationUserId == userId))
.ToList();
Please read this for why use Include in LINQ.

About Grails GORM's Where clause

Just a simple question here
I uses the following WHERE query
def instance = ClassName.where{varone == 'A' &&
vartwo == 'B' && varthree == 'C'}.list()
And it returned me the object that i wanted --> ClassName(unsaved)
But when i tried to do the following
def instance2 = ClassName.where{varone == params.varone &&
vartwo == params.vartwo && varthree == params.varthree}.list()
It returned me the following which i couldn't do anything on it --->
grails.gorm.DetachedCriteria#somenumbershere
I don't understand what are the differences between these two. I need the 2nd query to return the same object as what the first query returned.

Trying to count numbers of topics under a forum board

Here is what I currently have:
#Model.TPGForumTopicQuery.Select(m => m.closed != true && m.deleted != true)
.Where(m => m.TPGForumBoardID == item.boardID).Count()
This returns an odd error:
An error occurred during the compilation of a resource required to service this request.
Please review the following specific error details and modify your source code appropriately.
If I remove the .Select it works without error and counts all of the topics under the forum board. But the topics can be marked 'closed' or 'active' and I need to omit those in the count.
The above code is within a #foreach loop. So item.boardID is talking about the Forum Board.
Do not do the filter in the Select. Do it in the Where:
#Model.TPGForumTopicQuery.Where(m => m.TPGForumBoardID == item.boardID && m.closed != true && m.deleted != true).Count()
A bit of optimization:
Rather than m.closed != true, do !m.closed
#Model.TPGForumTopicQuery.Where(m => m.TPGForumBoardID == item.boardID && !m.closed && !m.deleted).Count()
And rather than get the Count after the Where-clause, you can pass in the where-clause to the Count():
#Model.TPGForumTopicQuery.Count(m => m.TPGForumBoardID == item.boardID && !m.closed && !m.deleted)

Differentiating between the two Ajax requests

I am making a search form with in the JqueryUI tabs. The tab contains the Ajax search form and a table showing the results from the search. Also I have used IpagedList to page through the result table.The Index action of the controller contains the Linq query and controls which view to render. Following is the code for Index action:
public ActionResult Index(ConsultantSearch model, int page = 1)
{
if (!String.IsNullOrEmpty(model.SearchButton) ||!String.IsNullOrEmpty(model.CancelButton))
{
var consultants = from con in db.Consultants
where (model.ConsultantName == null || con.ConsultantName.Contains(model.ConsultantName)) && (model.CompanyID == null || con.CompanyID == model.CompanyID)
&& (model.ClientID == null || con.ClientID == model.ClientID) && (model.VendorID == null || con.VendorID == model.VendorID) && (model.RecruiterID == null || con.RecruiterID == model.RecruiterID)
&& (model.Class == null || con.Class == model.Class) && (model.W2_1099 == null || con.W2_1099 == model.W2_1099) && (model.IsActive == null || con.IsActive == model.IsActive)
&& (model.StartDate == null || model.EndDate == null || (con.StartDate >= model.StartDate && con.EndDate <= model.EndDate))&&( model.StartDate == null || con.StartDate >= model.StartDate) && (model.EndDate == null|| con.EndDate <= model.EndDate)
select con;
consultants = consultants.Include(c => c.Client).Include(c => c.Company).Include(c => c.Recruiter).Include(c => c.SalesPerson).Include(c => c.Vendor);
return PartialView("_ConsultantList",consultants.ToList().ToPagedList(page,RecordsPerPage));
}
else
{
var consultants = db.Consultants.Include(c => c.Client).Include(c => c.Company).Include(c => c.Recruiter).Include(c => c.SalesPerson).Include(c => c.Vendor);
return PartialView(consultants.ToList().ToPagedList(page, RecordsPerPage));
}
}
When the user first loads the page the else part executes which renders the partial view Index which shows the form and the table showing all consultants currently in Database. However when the search button or cancel button is clicked the if condition gets true and the partial view Consultant list is rendered. Which updates only the result table part of the page.
Now my question is I want to add a condition in which when the paging control is used the If condition gets true and only the next page of consultant records in the result table are shown. I can use isAjaxRequest() in the If condition. But the problem is when the JqueryUI tab (containing the from and table) will load the If condition will become true because of the isAjaxRequest() and only Consultant List view will be rendered which I do not want.
So basically I want to differentiate between the two ajax requests..If the ajax request is for the tabs then the else condition should work and if it is from paging then the if condition should work.
Any ideas...?
Redesign your controller action method. Instead of placing conditional logic in your controller add an action method for each condition you need to satisfy and put the logic of which one to request in the view/markup.
The best way to tell if you should load your consultant grid or a paged view of some search results is if the view/JavaScript performs an ajax request to the appropriate action method.

IQueryable.Where clause AND not working with multiple search parameters

I am having an issue with getting a Multiple search working with a IQueryable.Where Clause using the AND operator. I know that the problem is when a parameter is blank or null it is searching for a "" with the other parameter and not returning results but I don't want to have to go through an extended and ridiculously nested if to check for nulls or blanks on 8 parameters. I have googled this for days, the OR works obviously but the AND condition returns nothing.
albums = albums.Where(a => a.CA_AlbumName.ToUpper().Contains(searchName.ToUpper()) &&
a.CA_AlbumURL.ToUpper().Contains(searchURL.ToUpper()));
The above works if both parameters are not blank but returns nothing if one of them is. I have tried building the where based on not null like below but same results:
if (!String.IsNullOrEmpty(searchName))
{
albums = albums.Where(a => a.CA_AlbumName.ToUpper().Contains(searchName.ToUpper()));
}
if (!String.IsNullOrEmpty(searchURL))
{
albums = albums.Where(a => a.CA_AlbumURL.ToUpper().Contains(searchURL.ToUpper()));
}
If I understand your requirement right, the following one should work:
albums = albums.Where(a =>
(
string.IsNullOrEmpty(searchName) ||
a.CA_AlbumName.ToUpper().Contains(searchName.ToUpper())
) &&
(
string.IsNullOrEmpty(searchURL) ||
a.CA_AlbumURL.ToUpper().Contains(searchURL.ToUpper())
)
);
#James is right. The updated code is here:
var isSearchNameNullOrEmpty = string.IsNullOrEmpty(searchName);
var isSearchURLNullOrEmpty = string.IsNullOrEmpty(searchURL);
albums = albums.Where(a =>
(
isSearchNameNullOrEmpty ||
a.CA_AlbumName.ToUpper().Contains(searchName.ToUpper())
) &&
(
isSearchURLNullOrEmpty ||
a.CA_AlbumURL.ToUpper().Contains(searchURL.ToUpper())
)
);

Resources