So I have been trying to do this for a couple of hours by now but I still can't get it
Tables are like this.
**Questions**
- IDQuestion, IDSubject, DNI, others..
**Answers**
- IDQuestion , IDAnswer, DNICreator, others..
**StudentsPersonalinformation (just to get names, nothing related to the answers)**
- name, surname, DNI, others..
What i want to do is within the linq query get the amount of answers of a question. What I already have is this
var querySubjectQuestions = (from questions in db.questions
join studentspersonalinformation in db.studentspersonalinformation on questions.DNI equals studentspersonalinformation.DNI
where questions.IDSubject == IDSubject && questions.status == 1
select new
{
IDQuestion = questions.IDQuestion,
Title = questions.title,
Date = questions.date,
studentName = studentspersonalinformation.name,
studentSurname = studentspersonalinformation.surname,
}).OrderByDescending(c => c.Date);
But still don't know where to put the .Count from the other table where the IDQuestion equals the one it is querying.
Thanks :)
var querySubjectQuestions = (from questions in db.questions
join studentspersonalinformation in db.studentspersonalinformation on questions.DNI equals studentspersonalinformation.DNI
where questions.IDSubject == IDSubject && questions.status == 1
select new
{
IDQuestion = questions.IDQuestion,
Title = questions.title,
Date = questions.date,
studentName = studentspersonalinformation.name,
studentSurname = studentspersonalinformation.surname,
noAnswers = (from answer in db.answers
where answer.IDQuestion == questions.IDQuestion)
select answer).Count()
}).OrderByDescending(c => c.Date);
Without your c# entities of your DB tables, this is the best I can do.
select new
{
IDQuestion = questions.IDQuestion,
Title = questions.title,
Date = questions.date,
studentName = studentspersonalinformation.name,
studentSurname = studentspersonalinformation.surname,
noAnswer = questions.Answers.Count()
}
Related
This question already has answers here:
Sequence contains no elements?
(7 answers)
Closed 10 months ago.
I try to get some data from few table with joining. This query is give an error as System.InvalidOperationException , Message=" Sequence contains no elements ". How can I avoid this error.
var assignments = (from s in _db.SubmissionLinks
join a in _db.Assignments on s.AssignmentID equals a.AssignmentID
join p in _db.Projects on a.ProjectID equals p.ID
join s2 in _db.SystemUsers on p.SystemUserFK equals s2.ID
select new AssignmentViewModel()
{
SubmissionlinkID = s.SubmissionLinkID,
SubmissionlinkName = s.SubmissionName,
ProjectID = p.ID,
ProjectName = p.ProjectName,
Deadline = s.Deadline,
Userid = s2.ID,
Assignmentid = a.AssignmentID,
IsActive = s.ActiveStatus
}).Where(s =>s.Userid == ID && s.IsActive == 0).Distinct().First();
I try to avoid that by checking returning objects inside of the where clause but it didn't work
var assignments = (from s in _db.SubmissionLinks
join a in _db.Assignments on s.AssignmentID equals a.AssignmentID
join p in _db.Projects on a.ProjectID equals p.ID
join s2 in _db.SystemUsers on p.SystemUserFK equals s2.ID
select new AssignmentViewModel()
{
SubmissionlinkID = s.SubmissionLinkID,
SubmissionlinkName = s.SubmissionName,
ProjectID = p.ID,
ProjectName = p.ProjectName,
Deadline = s.Deadline,
Userid = s2.ID,
Assignmentid = a.AssignmentID,
IsActive = s.ActiveStatus
}).Where(s => s != null && s.Userid == ID && s.IsActive == 0).Distinct().First();
Agree with Panagiotis; its supposed to be that SubmissionLink has a .Assignment property that returns the parent Assignment, Assignment has a .Project prop that returns the Project etc, and then you just do:
_db.SubmissionLinks
.Where(s =>s.Userid == ID && s.IsActive == 0)
.Select(s => s.Select(s => new AssignmentViewModel()
{
SubmissionlinkID = s.SubmissionLinkID,
SubmissionlinkName = s.SubmissionName,
ProjectID = s.Assignment.Project.ID,
ProjectName = s.Assignment.Project.ProjectName,
Deadline = s.Deadline,
Userid = s.Assignment.Project.SystemUser.ID,
Assignmentid = s.Assignment.AssignmentID,
IsActive = s.ActiveStatus
})
.SomethingThatRunsTheQueryLike_First_FirstOrDefault_ToList_etc
EF works out the rest from how it seens you use the navigations (s.Assignment.Project.ProjectName etc). Starting from the many end and going up to the one end is quite easy, because it's just a single object at the end of the nav. Going down through collections is a bit more of a nuisance, so think carefully about where you start your query from for the easiest life. For example if you wanted the Project and its most recent submission, you might:
db.Projects.Select(p => new Something{
p.ProjectName,
MostRecentLinkId = p.SubmissionLinks.OrderByDescending(sl => sl.CreatedDate).First().Id
})
That p.SubmissionLinks.OrderByDescending(sl => sl.CreatedDate).First().Id would be translated (by recent EFC) to something like ... ROW_NUMBER() OVER(PARTITION BY projectid ORDER BY createddate DESC) rn ... WHERE rn=1 in a subquery, but working with collections is usually that little more tricky because you're performing aggregations to make them make sense in the context of a single parent. If you can start from a different place so youre not digging into collections it's simpler
I'm new to the C#, I have a database that someone else designed, query works great, but compared with SQL, it's 10 times slower.
I made mistakes here for sure, anybody have tips to speed this up a little bit. This model is for displaying in table, and I converting int to ENUM and calculating discount for display.
Code is:
var results = from w in db.Washes.AsEnumerable()
join t in db.Wash_Types.AsEnumerable() on w.WashTypeId equals t.Id
join a in db.Accounts.AsEnumerable() on w.AccountId equals a.Id
orderby w.Id descending
select new AllWashesTable
{
Id = w.Id,
WashTime = w.WashTime,
WashTimeEnd = w.WashTimeEnd,
Name = a.Name,
Client = (w.Client != null ? w.Client.Naziv : ""),
MobileNumber = a.MobileNumber,
Identification = w.Identification,
WashType = WashTypeShowEnum.WashTypeShowEnumToString((WashTypeShowEnum.WashType) w.WashTypeId),
Price = int.Parse(t.WashPrice) * (1 - w.Discount) + "",
Discount = w.Discount
};
return results.ToList();
Seems all my entity queries are at least 5+ times slower than SQL. Somewhere I am making some mistake.
Your problem is the use of AsEnumerable. When the query gets executed (in your case the results.ToList()), Everything that appears after it, will be evaluated using linq-to-objects. It means that your joins will not be handled by DB. You will fetch all the records from the tables.
However, your function WashTypeShowEnum.WashTypeShowEnumToString will not be recognized by entity framework.
You might want to move the AsEnumerable to the end and then select the results.
var results = (from w in db.Washes
join t in db.Wash_Types on w.WashTypeId equals t.Id
join a in db.Accounts on w.AccountId equals a.Id
orderby w.Id descending
select new {w, a, t}).AsEnumerable().Select(arg=> new AllWashesTable
{
Id = arg.w.Id,
WashTime = arg.w.WashTime,
WashTimeEnd = arg.w.WashTimeEnd,
Name = arg.a.Name,
Client = (arg.w.Client != null ? arg.w.Client.Naziv : ""),
MobileNumber = arg.a.MobileNumber,
Identification = arg.w.Identification,
WashType = WashTypeShowEnum.WashTypeShowEnumToString((WashTypeShowEnum.WashType) arg.w.WashTypeId),
Price = int.Parse(arg.t.WashPrice) * (1 - arg.w.Discount) + "",
Discount = arg.w.Discount
};
return results.ToList();
I have only the very basics of LINQ. I speak SQL and JDBC, tasked with converting dynamic PL/SQL to LINQ Entity Framework. How can I add conditional WHERE clauses into LINQ queries? Here is a very simplified example (leaving out type info):
Q1 := 'SELECT bDay = b.birthday
address = b.address
FROM (' ;
Q2 := 'SELECT folks.birthday, Address.address
FROM folks,
(SELECT state,
surname AS name
FROM Individuals, Addresses
WHERE Individuals.addrId = Address.id
AND Addresses.state = 'CA' ) find1
,(SELECT state,
surname AS name
FROM Individuals, Addresses
WHERE Individuals.addrId = Address.id
AND Addresses.state = 'NV' ) find2
AND find1.state(+) = folks.state';
IF input_parm = 'RED' THEN
condAddOn :=condAddOn || 'AND folks.vacationHouse IS NOT NULL';
END IF;
IF input_parm = 'BLUE' THEN
condAddOn :=condAddOn || 'AND folks.vacationHouse = 'Cabin';
END IF;
...
OPEN curs FOR Q1 || Q2 || condAddOn ')b';
Trying to figure out the C#/LINQ syntax, here is my attempt (working bottom up):
var find1 = (from addr in Addresses
from indiv in Individuals
where indiv.addrId = addr.addrID
select new
{
indiv.state,
indiv.surname
});
var find1OuterJoin = (from person in folks
join f1 in find1 on person.addrId equals f1.addrID
from f1OutJn in temp.DefaultIfEmpty()
select new
{
f1OutJn.state,
f1OutJn.surname
});
var Q2 = (from person in folks
from addr in addresses
from f1 in find1OuterJoin
where person.addrId == addr.addrId
&& f1.state == folks.state
select new
{
person.birthday
,addr.address
});
var Q1 = (from q2 in Q1
select new
{bDay = b.birthday
,address = b.address
});
I don't know
1) if I introduced Q1 into the Q2 correctly
2) how to introduce the dynamic WHERE clauses
to end up with an equivalent cursor statement:
OPEN curs FOR Q1 || Q2 || condAddOn ')b';
Added: Can I use a functional or expression to include the dynamic bits? I saw a reference to Expression and Expandable(), but unsure.
Added: my attempt at the LINQ queries
When using the where method with link you are returned an IQueryable object. This does not immediately execute the statement, therefore it is possible to do the following:
var results = from person in folks
join addr in addresses
where person.addrId == addr.addrId
select new {
person.birthday,
addr.address
};
if(predicate){
results = from r in results
where /* new condition here */
select r;
}
var resultSet = results.ToList().AsEnumerable();
for other link operators, especially when using lambda linq you can also use the AsQuerably extension method.
such as, but not limited to:
var results = folks.join(address,
person => person.addrId,
addr => addr.addrId
(person, addr) => new {
person.birthday,
addr.address
}).AsQueryable();
if(predicate)
{
results = results.where(/*predicate for the where condition*/);
}
var resultSet = results.ToList().AsEnumerable();
I'm trying to use LINQ to CRM to get some data in a parent/child format. It's a One to Many and I don't want the Child records flattening with the Parent. Firstly is what I'm asking possible?
I do not have navigation properties and there will be many parents returned, in turn each parent will have many children.
I'm trying to avoid multiple queries, just fetching it in 1.
So I'm after:
So the parent has many Children and the children have some other lookup properties in other tables 1 to 1.
Parent
--Child + other info
--Child + other info
Parent
--Child + other info
Parent
--Child + other info
--Child + other info
--Child + other info
etc
I've tried getting the Details as a IQueryable first, then using that joined on the header:
var detailsOnly = (from det in db.details
join inc in db.Incidents on det.detOtherId equals inc.incidentid into incidentsLo
from subInc in incidentsLo.DefaultIfEmpty()
join cli in db.Accounts on subInc.accountid equals cli.accountid into accountsLo
from subCli in accountsLo.DefaultIfEmpty()
select new
{
det,
AccName = subAcc.name,
AccRef = subAcc.accountnumber,
IncidentTicketNumber = subInc.ticketnumber,
IncidentKeyDescription = subInc.title,
IncidentMainContact = subInc.maincontactname
});
var query = from head in db.headers
where head.IsDone == isdone & head.type == typeId & head.accountid == AccountId
select new MyHeader(head)
{
MyDetails = detailsOnly.Where(md => md.det.detOtherId == head.headOtherId)
.Select(d => new MyDetail(d.det)
{
AccName = d.AccName,
AccRef = d.AccRef,
IncidentTicketNumber = d.IncidentTicketNumber,
IncidentKeyDescription = d.IncidentKeyDescription,
IncidentMainContact = d.IncidentMainContact
}).ToList()
};
var result = query.ToList();
It doesn't look like this is getting a real answer, so the best I can say is to execute the details collecting part, group it, then select the other parts from that.
var detailsOnly = (from det in db.details
join inc in db.Incidents on det.detOtherId equals inc.incidentid into incidentsLo
from subInc in incidentsLo.DefaultIfEmpty()
join cli in db.Accounts on subInc.accountid equals cli.accountid into accountsLo
from subCli in accountsLo.DefaultIfEmpty()
select new MyDetail(det)
{
AccName = subAcc.name,
AccRef = subAcc.accountnumber,
IncidentTicketNumber = subInc.ticketnumber,
IncidentKeyDescription = subInc.title,
IncidentMainContact = subInc.maincontactname
}).ToArray();
var groupedDetails = detailsOnly.GroupBy(c => c.det.detOtherId);
var query = db.headers.Where(head => head.IsDone == isdone
&& head.type == typeId
&& head.accountid == AccountId);
var result = query.Join(groupedDetails, c => c.headOtherId, c => c.Key, (a, b) => new MyHeader(a) { MyDetails = b })).ToList();
I could be way off on that, but you see the gist. I don't think it's the best way, but I don't have any experience with LINQ-to-CRM so I don't know. Something like this should work, though. Better than nothing. There might also be syntax errors, because this hasn't been tested.
I've probably spent 40 hours on this problem so far, I've tried every solution on this site and on google, and I still can't make this work.
I need to left join a table to the results of a previous query, stored in a var. The joining field is a varchar in the table queried for the result in the var, and a bigint (long) in the table being joined. Here is the current attempt, which tells me "Object reference not set to an instance of an object." All Entities errors seem like nonsense and lies to me, I assume it's trying to tell me nothing matched, but who knows.
List<reportUser> ru = leaders
.GroupJoin(db.sweeps,
a => a.FBID.ToString(),
s => s.userFBID.First().ToString(),
(a, matching) => new reportUser
{
FBID = a.FBID,
CurrentPoints = a.CurrentPoints,
Name = matching.FirstOrDefault().Name,
Email = matching.FirstOrDefault().email
}
?? new reportUser
{
FBID = 0,
CurrentPoints = 0,
Name = "",
Email = ""
})
.Select(a => a)
.ToList();
Here's the SQL requested below. I've included the SQL to build the Leaders object as well, all the above is really meant to represent is the last line, which is simply a left join.
select s.name, s.email, b.score, c.score overall
from (
select a.userfbid, sum(a.pointvalue) score
from (
select userfbid, pointvalue
from l
left join qa on qa.id = l.qaid
left join q on q.id = qa.qid
left join qz on qz.id = q.qzid
where qa.pointvalue > 0 and qz.cid = 12
union all
select fbid userfbid, pointvalue
from bn
where date >= '5/9/2011 04:00' and
date <= '5/16/2011 04:00'
) a
group by a.userfbid
) b
left join (
select a.userfbid, sum(a.pointvalue) score
from (
select userfbid, pointvalue
from l
left join qa on qa.id = l.qaid
left join q on q.id = qa.qid
left join qz on qz.id = q.qzid
where qa.pointvalue > 0
union all
select fbid userfbid, pointvalue
from bn
) a
group by a.userfbid
) c on c.userfbid=b.userfbid
left join s on s.userfbid=b.userfbid
order by score desc
I'm assuming that in your database s.userFBID.First() is never null?
If that's right, then your problem could be in the FirstOrDefault().Name type statements - when FirstOrDefault() evaluates to null then obviously you will get a nullreferenceexception :/
To get around this, try something like:
List<reportUser> ru = leaders
.GroupJoin(db.sweeps,
a => a.FBID.ToString(),
s => s.userFBID.First().ToString(),
(a, matching) =>
{
var match = matching.FirstOrDefault();
return match != null ?
new reportUser
{
FBID = a.FBID,
CurrentPoints = a.CurrentPoints,
Name = match.Name,
Email = match.email
}
: new reportUser
{
FBID = 0, // a.FBID ?
CurrentPoints = 0, // a.CurrentPoints ?
Name = "",
Email = ""
}})
.Select(a => a)
.ToList();
However, I find it a bit hard to do this without seeing the structure of the database... or some sample data
Once you've got something working... then I highly recommend you try breaking this down into something more easily understandable - I'm really not sure what's going on here!
Here's a simple left outer join for you:
var query = from l leaders
join s in db.sweeps on l.FBID equals s.userFBID.First() into joined
from j in joined.FirstOrDefault()
select new reportUser
{
FBID = l.FBID,
CurrentPoints = l.CurrentPoints,
Name = j == null ? string.Empty : j.Name,
Email = j == null ? string.Empty : j.email
}
If this isn't quite what you are looking for... maybe try posting the SQL for what you actually want.