For some reason I am getting a "Query body must end with a select clause or a group clause" compile error on what seems to be a simple compound conditional in the following linq-to-sql query:
using (var db = new CaremcDB(Database.Conn))
{
var taxids = from p in db.ProviderTaxIds
join c in db.CustomerProviders
on customerId equals c.CustomerId && p.Id equals c.ProviderId
select p;
return taxids.ToList<ProviderTaxIds>();
}
It chokes on the "&& p.Id equals c.ProviderId" clause for some reason.
It appears that customerId is an external input to the query. Move that to a where clause.
...
on p.Id equals c.ProviderId
where customerId == c.CustomerId
select p;
try this, the parameter names just need to match in the anonymous object
join c in db.CustomerProviders on new { customerId, p.Id } equals new { customerId = c.CustomerId, Id= c.ProviderId }
Related
I have two related tables Ticket and Status.
Every ticket can be multiple status. (Open, assigned, closed). But I want all tickets but only one status (newest date) to show.
I could handle with this query on t-sql;
SELECT d.ticketID, statusName, c.statusDate, c.assignedTo,c.statusID
FROM Ticket d LEFT JOIN Status c ON c.ticketID = d.ticketID
WHERE c.statusID = (
SELECT MAX(statusID)
FROM Status c2
WHERE c2.ticketID = d.ticketID)
This is my Linq :
var result = from t in db.Ticket
join s in db.Status.OrderByDescending(x=>x.statusDate).Take(1)
on t.ticketID equals s.ticketID join c in db.Customer
on t.customerID equals c.customerID
But this only returning one row.
I solve my problem with linqer application via converting my Tsql query to linq
from s in db.Status
where s.statusID ==
(from c2 in db.Status where
c2.ticketID == s.Ticket.ticketID &&
c2.statusName == "New" ||
c2.statusName == "Assigned"
select new
{
c2.statusID
}).Max(p => p.statusID)
Thanks for everyone.
Try changing your original linq logic to:
var result = from t in db.Ticket
join s in db.Status on t.ticketID equals s.ticketID into sGroup
from s in sGroup.OrderByDescending(x=>x.statusDate).Take(1)
join c in db.Customer
on t.customerID equals c.customerID
The concat works, but the outer distinct query does not. The error is 'string does not contain a definition for 'role_name'... Any idea how to make this work?
(from results in ((from pmr in dbContext.project_member_role
join r in dbContext.role on pmr.project_member_role_id equals r.role_id
where pmr.member_id == memberId
select r.role_name)
.Concat(from m in dbContext.member
join r in dbContext.role on m.portal_role_id equals r.role_id
where m.member_id == memberId
select r.role_name))
select results.role_name).Distinct().ToList();
I'm trying to select the MatchingObjects that doesn't exist in the Unlock table , I have this SQL query as following:
select a.* from MatchingObjects a
left join Unlocks b
on a.ObjectCategoryId = b.ObjectCategoryId
left join Members c
on b.StudentId = c.Id
and b.StudentId = #studentId
where b.ObjectCategoryId is null
and c.id is null
order by a.ObjectCategoryId
And a LINQ query
var query = (from d in db.ObjectCategories
join a in db.MatchingObjects on d.Id equals a.ObjectCategoryId into grp3
join b in db.Unlocks
on d.Id equals b.ObjectCategoryId into grp1
from m in grp1.DefaultIfEmpty()
join c in db.Members
on m.StudentId equals c.Id into grp2
from n in grp2.DefaultIfEmpty()
where m.ObjectCategoryId == null
&& n.Id == null
orderby d.Id).AsEnumerable()
;
However, the LINQ query is not showing the same result as that I want like in the SQL query. Could you guys tell me what I should change in my LINQ Query?
This is the model:
Better you can use below tools:
An SQL-> LINQ converter..
http://www.sqltolinq.com
http://www.linqpad.net/
try this one
var query = from m in db.MatchingObjects.Where(w => w.ObjectCategoryId == null)
join u in db.Unlocks.Where(w => w.studentId == #studentId)
on m.ObjectCategoryId equals u.ObjectCategoryId into joinedU
from ju in joinedU.DefaultIfEmpty()
join m in db.Members.Where(w => w.id == null)
on ju.StudentId equals m.Id into joinedM
from jm in joinedM.DefaultIfEmpty()
select m;
But your request is a bit Strange. You make the join by ObjectCategoryId and in the Where clause you put ObjectCategoryId == null!!!
sorry guys, the Sql and the LINQ query was a bit different in table selection. I'm sorry about that because I was trying different Linq while posting the question, but The main problem is at the join clause
(from d in db.ObjectCategories
join a in db.MatchingObjects
on d.Id equals a.ObjectCategoryId into grp3
join b in db.Unlocks
on d.Id equals b.ObjectCategoryId into grp1
from m in grp1.DefaultIfEmpty()
join c in db.Members
on m.StudentId equals studentId into grp2
from n in grp2.DefaultIfEmpty()
where m.ObjectCategoryId == null
where n.Id == null
orderby d.Id).AsEnumerable()
/* this is the correct one */
join c in db.Members
on m.StudentId equals studentId into grp2
/* the below was the original incorrect join clause*/
join c in db.Members
on m.StudentId equals c.Id into grp2
I am trying to do this simple sql query to LINQ. But its give me error.
Here is the SQL query that need to conver to LINQ
DECLARE #groupID int
SET #groupID = 2
SELECT *
FROM dbo.Person p
LEFT JOIN dbo.PersonGroup pg ON ( p.PersonID = pg.PersonID AND pg.GroupID = #groupID)
Ignore #groupID. which will be provided as function parameter for LINQ query.
Here is LINQ query what i have tried.
from p in Person
join pg in PersonGroup on new { p.PersonID, groupID } equals new { pg.PersonID, pg.GroupID } into t
from rt in t.DefaultIfEmpty()
Where groupID is provided as function parameter. Both GroupID and PersonID are int. But it gives me following error,
Error 2 The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'GroupJoin'.
Little help would be appreciated.
Your Code
from p in Person
join pg in PersonGroup on new { p.PersonID, groupID } equals new { pg.PersonID, pg.GroupID } into t
from rt in t.DefaultIfEmpty()
Change it to
from p in Person
join pg in PersonGroup on new { Person = p.PersonID, Group = groupID } equals new { Person = pg.PersonID, Group = pg.GroupID } into t
from rt in t.DefaultIfEmpty()
That way it will join using the Anonymous type
I need to get the id value from Table1 which is a Guid. This query can return a null also. So I started with following
Guid? SomeID = from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id;
But I get following compilation error.
Cannot implicitly convert type 'System.Linq.IQueryable'
to 'System.Guid?'
Changing Guid? to Guid didn't help.
Guid SomeID = from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id;
as now I get following error.
Cannot implicitly convert type 'System.Linq.IQueryable'
to 'System.Guid'
What am I doing wrong?
Your query returns all matching guids and it has type IQueryable<Guid?>
IQueryable<Guid?> guids =
from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id;
If you need one guid, use First, Single, FirstOrDefault, or SingleOrDefault
Guild? guid = guids.FirstOrDefault();
Or in single statement:
Guid? guid = Table1.Where(R => R.Name == "blah")
.Join(Table2, R => R.Id, P => P.Id2, (R,P) => R.Id)
.FirstOrDefault();
Mixed syntax (unfortunately there is no equivalent for FirstOrDefault operator in query syntax):
Guid? guid = (from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id).FirstOrDefault();
Enumerable.Select returns an IEnumerable<T> which is a sequence, so normally multiple items. If you want the first item use First or (if it can be empty) FirstOrDefault:
Guid? SomeID = (from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id).First();
The return value of that LINQ statement is a list of GUIDs. Specifically, an IEnumerable<Guid>.
Call .First() on the result of your query if you're just expecting one result, or .FirstOrDefault() if you might end up with no results and you just want to receive a null.
(from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id).FirstOrDefault() //or .SingleOrDefault()
IQueryable represents query for some kind of store (e.g. SQL Server) and can potentially return 0,1 or more rows. You are trying to get one of them. To get single row use methods like First/FirstOrDefault or Single/SingleOrDefult
You need to use Single or SingleOrDefault or First, or FirstOrDefault method. They exist only in lambda syntax. If you expect one result use Single, if one or zero, then SingleOrDefault.
Try this code
use as Guid
Look below :
Guid SomeID = (from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id).First() as Guid;
or try it
Guid SomeID = (Guid) from R in Table1
join P in Table2
on R.Id equals P.Id2
where R.Name == 'blah blah'
select R.Id).First();