What is the difference between these two linq queries? The first one will not work. The second will. Why? - linq

I have my code using the following linq:
var consulta = from grupo in Contexto.Set<GRUPOCONTRATO>()
join detalhe in Contexto.Set<GRUPOCONTRATODETALHE>()
on grupo.CDGRUPOCONTRATO equals detalhe.CDGRUPOCONTRATO
where grupo.NOGRUPOCONTRATO.Contains("FACIL")
&& detalhe.NRCONTRATO == carteira.NumeroDoContrato
select detalhe;
PlanoFacil = consulta.Any();
The code above wont work and throws an exception like this:
Object of type 'System.Data.Objects.ObjectQuery1[Dominio.PERICIA]' cannot be converted to type 'System.Data.Entity.IDbSet1[Dominio.PERICIA]'.
Please note that it points to a problem with another entity (PERICIA) which has nothing to do with the query and has no relationship with the two entities in the query...
But if I split the query like this it works:
var consulta = from grupo in Contexto.Set<GRUPOCONTRATO>()
join detalhe in Contexto.Set<GRUPOCONTRATODETALHE>()
on grupo.CDGRUPOCONTRATO equals detalhe.CDGRUPOCONTRATO
where grupo.NOGRUPOCONTRATO.Contains("FACIL")
//&& detalhe.NRCONTRATO == carteira.NumeroDoContrato
select detalhe;
PlanoFacil = consulta.Any(detalhe => detalhe.NRCONTRATO == carteira.NumeroDoContrato);
Why?

Related

How to solve this Error in Linq : Operator '!=' cannot be applied to operands of type 'int' and 'System.Linq.IQueryable<int>'

var ll = from a in db.EmployeeMasters
where a.EmployeeID != (from d in db.EmployeeMasters
join c in db.PerformanceDetails on d.EmployeeID equals c.EmployeeID
join z in db.ProjectMasters on c.ProjectID equals z.ProjectID
into ss
from z in ss.DefaultIfEmpty()
where z.ProjectName == name || z.ProjectName == name1
select d.EmployeeID)
select a.EmployeeName;
It returns an error messages like below
Operator '!=' cannot be applied to operands of type 'int' and 'System.Linq.IQueryable'
I want to add this Linq query in http post method to view output in postman
Anyone Please help me to solve this
Actual question is select employees who are not part of 2 projects like (CRM, Automation)
Part of both project employees are in another project but some of the employees not in any projects
My Entity Framework Data Model is shown here:
name and name1 are given parameters for project names
You're making this much harder than necessary. In the first place, you should use these navigation properties EF kindly creates for you, instead of using verbose and error-prone join statements. Doing that, it's much easier to write a greatly simplified predicate:
var ll = from a in db.EmployeeMasters
where !a.PerformanceDetails
.Any(pd => pd.ProjectMaster.ProjectName == name
|| pd.ProjectMaster.ProjectName == name1)
select a.EmployeeName;
This is a different query --it translates into EXISTS-- but the result is the same and the query plan may even be better. Also, it's much easier to add more predicates to it later, if necessary.
Your question isn't really clear, but the error is pretty clear, you cannot compare type int and System.Linq.IQueryable<int>.
I assume your want something like this :
var ll = from a in db.EmployeeMasters
where !(from d in db.EmployeeMasters
join c in db.PerformanceDetails on d.EmployeeID equals c.EmployeeID
join z in db.ProjectMasters on c.ProjectID equals z.ProjectID
into ss
from z in ss.DefaultIfEmpty()
where z.ProjectName == name || z.ProjectName == name1
select d.EmployeeID).Contains(a.EmployeeID)
select a.EmployeeName;
Here we're looking for EmployeeIDs that do not appear in your query result.
int[] EmployeeIDs = (from em in db.EmployeeMasters
join pd in db.PerformanceDetails on em.EmployeeID equals pd.EmployeeID into pdRes
from pdResult in pdRes.DefaultIfEmpty()
join pm in db.ProjectMasters on pdResult.ProjectID equals pm.ProjectID into pmRes
from pmResult in pmRes.DefaultIfEmpty()
where (pmResult.ProjectName == "Automation" || pmResult.ProjectName == "CRM Customer")
select em.EmployeeID
).Distinct().ToArray();
var empResult = (from em in db.EmployeeMasters
where !EmployeeIDs.Contains(em.EmployeeID)
select new
{
EmployeeName = em.EmployeeName
}).ToList();

LINQ Error when using multiple JOIN in same statement on CRM 2011 Plug-in

Hi I am trying to join multiple entities in CRM 2011 but I get and error saying: {"'xrmsm_sessionEnrollments' entity doesn't contain attribute with Name = 'xrmsm_termsid'."}. That is correct but I am joining the entity that have that attribute.
My Linq Query:
var query2 = from e in svsContext.xrmsm_sessionEnrollmentsSet
join s in svsContext.xrmsm_sessionsSet on e.xrmsm_SessionLookup.Id equals s.xrmsm_sessionsId
join ic in svsContext.xrmsm_institutionCoursesSet on s.xrmsm_institutionCourseLookup.Id equals ic.xrmsm_institutionCoursesId
join ts in svsContext.xrmsm_term_sessionsSet on e.xrmsm_termSessionLookup.Id equals ts.xrmsm_term_sessionsId
join t in svsContext.xrmsm_termsSet on ts.xrmsm_TermLookup.Id equals t.xrmsm_termsId
where (e.xrmsm_StudentLookup.Equals(studentlookup)
&& e.xrmsm_YearLookup.Equals(entity.GetAttributeValue("xrmsm_studentlookup"))
&& ic.xrmsm_institutionCoursesId == institutionCourseGuid
&& t.xrmsm_termsId == termGuid)
select new { sessionName = s.xrmsm_sessionsName, StudentName = e.xrmsm_studentsName, StudentId = e.xrmsm_StudentLookup.Name };
My original SQL query that works on SQL Server:
SELECT en.xrmsm_currentsessionenrollmentsname
,en.xrmsm_isreadonlyname
,en.xrmsm_sessionenrollmentsaverage
,en.xrmsm_sessionenrollmentsgrade
,en.xrmsm_sessionenrollmentsid
,en.xrmsm_sessionenrollments_id
,en.xrmsm_sessionlookup as sessionid
,en.xrmsm_sessionlookupname
,en.xrmsm_sessionsname
,en.xrmsm_studentlookup AS studentid
,en.xrmsm_studentlookupname
,en.xrmsm_studentsname
,en.xrmsm_termsessionlookup
,en.xrmsm_termsessionlookupname
,en.xrmsm_withdrawal
,en.xrmsm_yearaverage
,en.xrmsm_yeargrade
,en.xrmsm_yearlookup
,en.xrmsm_yearlookupname
FROM CoseyTest_MSCRM.dbo.Filteredxrmsm_sessionEnrollments as en INNER JOIN
CoseyTest_MSCRM.dbo.Filteredxrmsm_sessions crmsessions ON
(en.xrmsm_sessionlookup = crmsessions.xrmsm_sessionsid AND en.xrmsm_yearlookup = crmsessions.xrmsm_yearlookup)
INNER JOIN Filteredxrmsm_institutionCourses institutionCourses
on crmsessions.xrmsm_institutioncourselookup = institutionCourses.xrmsm_institutioncoursesid
Inner Join Filteredxrmsm_term_sessions as termsession
on en.xrmsm_termsessionlookup = termsession.xrmsm_term_sessionsid
Inner Join Filteredxrmsm_terms as terms
on termsession.xrmsm_termlookup = terms.xrmsm_termsid
where en.xrmsm_yearlookup = '4BA07BED-3F51-E211-8359-00155D004403'
and en.xrmsm_studentlookup = 'C844AF65-5B51-E211-8359-00155D004403'
and terms.xrmsm_termsid = 'D1D107B7-4551-E211-8359-00155D004403'
and institutionCourses.xrmsm_institutioncoursesid = '2121914E-4551-E211-8359-00155D004403'
Linq provider for CRM has some limitations. You can fount it here. Check if your query violates limitations.
Try having a look at the actual query that it is generating and run that in SQL, it may help understand what is going on.
It could be that something your doing in LINQ is not available in CRM as paramosh mentioned but I can't see anything that jumps out at me.
Thanks for all your responses. I did the following workaround.
Make a query that retrieve a list of all the Student enrollments
Use the Find method of the List<T> class to find if a record exist with the conditions I am searching for.
var query2 = (from e in svsContext.xrmsm_sessionEnrollmentsSet
join s in svsContext.xrmsm_sessionsSet on e.xrmsm_SessionLookup.Id equals s.xrmsm_sessionsId
join ic in svsContext.xrmsm_institutionCoursesSet on s.xrmsm_institutionCourseLookup.Id equals ic.xrmsm_institutionCoursesId
join ts in svsContext.xrmsm_term_sessionsSet on e.xrmsm_termSessionLookup.Id equals ts.xrmsm_term_sessionsId
join t in svsContext.xrmsm_termsSet on ts.xrmsm_TermLookup.Id equals t.xrmsm_termsId
where (e.xrmsm_StudentLookup.Equals(studentlookup))
select new
{
EnrollmentId = e.xrmsm_sessionEnrollments_id,
SessionId = s.xrmsm_sessions_id,
EnrollmentYear = e.xrmsm_YearLookup,
InstitutionCourseId = (Guid)ic.xrmsm_institutionCoursesId,
TermId = (Guid)t.xrmsm_termsId,
Student = e.xrmsm_StudentLookup
}).ToList();
var q = query2.Find(r => r.EnrollmentYear.Id == entity.GetAttributeValue<EntityReference>("xrmsm_yearlookup").Id
&& r.InstitutionCourseId == institutionCourseGuid
&& r.TermId == termGuid);

LINQ to Entities three table join query

I'm having a bit trouble with a query in Linq to Entities which I hope someone can shed a light on :-) What I'm trying to do is to create a query that joins three tables.
So far it works, but since the last table I'm trying to join is empty, the result of the query doesn't contain any records. When I remove the last join, it gives me the right results.
My query looks like this:
var query = from p in db.QuizParticipants
join points in db.ParticipantPoints on p.id
equals points.participantId into participantsGroup
from po in participantsGroup
join winners in db.Winners on p.id
equals winners.participantId into winnersGroup
from w in winnersGroup
where p.hasAttended == 1 && p.weeknumber == weeknumber
select new
{
ParticipantId = p.id,
HasAttended = p.hasAttended,
Weeknumber = p.weeknumber,
UmbracoMemberId = p.umbMemberId,
Points = po.points,
HasWonFirstPrize = w.hasWonFirstPrize,
HasWonVoucher = w.hasWonVoucher
};
What I would like is to get some records even if the Winners table is empty or there is no match in it.
Any help/hint on this is greatly appreciated! :-)
Thanks a lot in advance.
/ Bo
If you set these up as related entities instead of doing joins, I think it will be easier to do what you're trying to do.
var query = from p in db.QuizParticipants
where p.hasAttended == 1 && p.weeknumber == weeknumber
select new
{
ParticipantId = p.id,
HasAttended = p.hasAttended,
Weeknumber = p.weeknumber,
UmbracoMemberId = p.umbMemberId,
Points = p.ParticipantPoints.Sum(pts => pts.points),
HasWonFirstPrize = p.Winners.Any(w => w.hasWonFirstPrize),
HasWonVoucher = p.Winners.Any(w => w.hasWonVoucher)
};
This is assuming hasWonFirstPrize and hasWonVoucher are boolean fields, but you can use any aggregate function to get the results you need, such as p.Winners.Any(w => w.hasWonFirstPrize == 1)
I don't use query syntax a lot but I believe you need to change from w in winnersGroup to from w in winnersGroup.DefaultIfEmpty()

How to do a simple Count in Linq?

I wanted to do a paging style table, but NeerDinner example fetches the entire data into a PaggingList type, and I have more than 10 000 rows to be fetched, so I skipped that part.
so I come up with this query
var r = (from p in db.Prizes
join c in db.Calendars on p.calendar_id equals c.calendar_id
join ch in db.Challenges on c.calendar_id equals ch.calendar_id
join ca in db.ChallengeAnswers on ch.challenge_id equals ca.challenge_id
join cr in db.ChallengeResponses on ca.challenge_answer_id equals cr.challenge_answer_id
where
p.prize_id.Equals(prizeId)
&& ch.day >= p.from_day && ch.day <= p.to_day
&& ca.correct.Equals(true)
&& ch.day.Equals(day)
orderby cr.Subscribers.name
select new PossibleWinner()
{
Name = cr.Subscribers.name,
Email = cr.Subscribers.email,
SubscriberId = cr.subscriber_id,
ChallengeDay = ch.day,
Question = ch.question,
Answer = ca.answer
})
.Skip(size * page)
.Take(size);
Problem is, how can I get the total number of results before the Take part?
I was thinking of:
var t = (from p in db.JK_Prizes
join c in db.JK_Calendars on p.calendar_id equals c.calendar_id
join ch in db.JK_Challenges on c.calendar_id equals ch.calendar_id
join ca in db.JK_ChallengeAnswers on ch.challenge_id equals ca.challenge_id
join cr in db.JK_ChallengeResponses on ca.challenge_answer_id equals cr.challenge_answer_id
where
p.prize_id.Equals(prizeId)
&& ch.day >= p.from_day && ch.day <= p.to_day
&& ca.correct.Equals(true)
&& ch.day.Equals(day)
select cr.subscriber_id)
.Count();
but that will do the query all over again...
anyone has suggestions on how can I do this effectively ?
If you take a query as such:
var qry = (from x in y
select x).Count();
...LINQ to SQL will be clever enough to make this a SELECT COUNT query, which is potentially rather efficient (efficiency will depend more on the conditions in the query). Bottom line is that the count operation happens in the database, not in LINQ code.
Writing my old comments :Well i was facing the same issue some time back and then i came up with LINQ to SP =). Make an SP and drop that into your entities and use it.you can get write Sp according to your need like pulling total record column too. It is more easy and fast as compare to that whet you are using wright now.
You can put count for query logic as well as, see the sample as below:
public int GetTotalCountForAllEmployeesByReportsTo(int? reportsTo, string orderBy = default(string), int startRowIndex = default(int), int maximumRows = default(int))
{
//Validate Input
if (reportsTo.IsEmpty())
return GetTotalCountForAllEmployees(orderBy, startRowIndex, maximumRows);
return _DatabaseContext.Employees.Count(employee => reportsTo == null ? employee.ReportsTo == null : employee.ReportsTo == reportsTo);
}

SubSonic3 linq problem

I have this query:
var rights = from gu in db.GroupUsers
join g in db.Groups on gu.GroupId equals g.GroupId
join gr in db.GroupRights on g.GroupId equals gr.GroupId
join r in db.Rights on gr.RightId equals r.RightId
where gu.UserId == userId && g.IsDeleted == false
select r;
It gets translated to:
SELECT [t0].[Name] AS Name1, [t0].[RightId] AS RightId1
FROM [dbo].[GroupUsers] AS t1
INNER JOIN [dbo].[Groups] AS t2
ON ([t1].[GroupId] = [t2].[GroupId])
INNER JOIN [dbo].[GroupRights] AS t3
ON ([t2].[GroupId] = [t3].[GroupId])
INNER JOIN [dbo].[Rights] AS t0
ON ([t3].[RightId] = [t0].[RightId])
WHERE (([t1].[UserId] = 3345) AND ([t2].[IsDeleted] = 0))
This is still ok, but in .NET my SubSonic objects are all empty. So the query returns 15 objects, but Name and RightId are an empty string and -1.
Can this have anything to do with the fact that Name is returned as Name1 and RightId is returned as RightId1?
I'll have a look into the source code of SubSonic3 to find something.
SubSonic3 Source Code: the query does get translated to the sql above. Because of the Name1 and RightId1, the Load in Database.cs doesn't work properly. The line :
currentProp = cachedProps.SingleOrDefault
(x => x.Name.Equals(pName, StringComparison.InvariantCultureIgnoreCase));
doesn't find the currentProp because the currentProp is Name (and RightId) and not Name1 and RightId1. Well, fixing this won't be for today. Maybe someone from SubSonic3 can have a look at this, because it's pretty annoying. I could write a sort of hack into the source code, but it won't be pretty. I guess the translation should be cleaned up so that Name1 and RightId1 are translated back to Name and RightId.
In TSqlFormatter.cs there's next line that adds these AS strings
(in method :
protected override Expression VisitSelect(SelectExpression select)
{
...
if (!string.IsNullOrEmpty(column.Name) && (c == null || c.Name != column.Name))
{
sb.Append(" AS ");
sb.Append(column.Name);
}
...
}
If I put the two Appends in comment, then my linq query does work and I do get the right data. But I guess those two lines are there for a reason, but what reason? In which usecase are the two lines necessary?

Resources