I'm kind of new to LINQ and I'm trying to represent the following query in LINQ to Entities:
Select * from Cotations CT1
where CT1.CotationID = iCot_ID and
Revision =
(select max(revision)
from Cotations CT2
where CT1.CotationID = CT2.Cotation)
where iCot_ID is an external parameter, and Cotations is my entity set.
Better yet, how can I represent this as an association between two entities?
If I have the following entities:
MasterLog:
--cotationID
Cotation:
--Cotationid
--Revision key,
and for each MasterLog I want to have an association with Cotation based only on CotationID where Revision is max for that cotation (as in above query)
Thanks.
Lukasz
I think you have overcomplicated your query. The below should do it.
int iCot_ID = 0;
var query = (
from c in context.Coalation
.Where(x=>x.Cotationid == iCot_ID)
.OrderByDesc(x=>x.Revision)
)
.FirstOrDefault();
I don't quite understand the second half of your question. Please take some time and further explain what you would like to do with MasterLog.
Here is a guess:
var cQuery = (
from c in context.Coalation
group c by g.Revision into g
orderby g.Revision descending
select g.First()
);
var mQuery = (
from m in MasterLog
join c in cQuery
on m.cotationID equals c.Cotationid
where
m.Cotationid==iCot_ID
select new {
MasterLog = m,
Cotation = c
}
);
Related
I'm having trouble getting my Linq statemnt to work when doing an outer join and a group by. Here's a SQL version of what I'm trying to accomplish:
select p.PRIMARY_KEY, min(p.EFFECTIVE_DATE), sum(IsNull(c.PAID_INDEMNITY, 0))
from PRMPOLCY p
left outer join CLMMAST c on p.PRIMARY_KEY = c.POLICY_NO
where p.UNDERWRITER_UID = 93
GROUP BY p.PRIMARY_KEY
Here's what I have in Linq (which doesn't work):
var result = from p in context.PRMPOLCies
join c in context.CLMMASTs on p.PRIMARY_KEY equals c.POLICY_NO into polClm
where (p.UNDERWRITER_UID == underwriter)
from grp in polClm.DefaultIfEmpty()
group grp by p.PRIMARY_KEY into g
select new PolicySummation()
{
PolicyNo = g.Key,
Incurred = g.Sum(grp => grp.PAID_INDEMNITY ),
EffDate = g.Min(grp => grp.PRMPOLCY.EFFECTIVE_DATE
};
Beating my head against the wall trying to figurwe this out!
Assuming you have a navigation property set up between PRMPOLCY and CLMMAST, you shouldn't need to specify the join explicitly. It's much easier to express most queries in linq without explicit joins, but rather treating your structures as a hierarchy. I don't know the specifics of your model property names, but I'd take a guess that something like this would work.
var result =
from p in context.PRMPOLCies
where (p.UNDERWRITER_UID == underwriter)
select new PolicySummation {
PolicyNo = p.PRIMARY_KEY,
Incurred = p.CLMASTs.Select(c => c.PAID_INDEMNITY).DefaultIfEmpty().Sum(),
EffDate = p.EFFECTIVE_DATE,
};
You need to include both your tables in the group clause like this:
group new { p, grp } by p.PRIMARY_KEY into g
Then in your Sum / Min
g.Sum(grp => grp.grp == null ? 0 : grp.grp.PAID_INDEMNITY )
g.Min(grp => grp.p.PRMPOLCY.EFFECTIVE_DATE)
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()
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);
}
var emailToProcess =
from a in db.EmailNotToProcess
join b in EmailUids on a.ENTPUId equals b.Uid
where a.ENTPUId != b.Uid
select b;
Here EmailUids is a List and EmailUid is a struct inside the struct we have two option like
public int EmailId;
public string Uid;
this ..
so I am executing the query but I am not able to count the how much record in this query...
thanks....
You can use the Count() method:
var emailToProcess = from a in db.EmailNotToProcess
join b in EmailUids on a.ENTPUId equals b.Uid
where a.ENTPUId != b.Uid
select b;
int emailCount = emailToProcess.Count();
You are trying to join an SQL Table via Linq-SQL with an external List, which I dont think is supported
If there are only a handful of ID's in the List then you can use Contains. This will pass each integer to SQL as a parameter:
var emailToProcess = from a in db.EmailNotToProcess
where !EmailUids.Select(u => u.Uid).Contains(a.ENTPUId)
select b;
int count = emailToProcess.Count();
NOTE:
If there are 1000's of IDs in EmailUids then you'll have to rethink your strategy. Either move the list of ID's into a SQL table (so LinqToSQL can perform the translation from LINQ to raw SQL) or you will have to pull back the entire rowset for EmailNotToProcess and then perform the join on the client.
It's hard to advise without knowing how much data you're dealing with in each table/list.
Maybe with a Contains:
var emailToProcess =
from mail in
(from a in db.EmailNotToProcess
where EmailUids.Select(e => e.Uid).Contains(a.ENTPUI)
select a).AsEnumerable()
join b in EmailUids on mail.ENTPUId equals b.Uid
where mail.ENTPUId != b.Uid
select b;
int count = emailToProcess.Count();
I've been looking through related LINQ questions here trying to figure this one out, but I'm having some trouble converting a SQL query of mine to the equivalent LINQ to Entities version.
select companies.CommpanyName,
job.Position,
count(offers.jobID) As Offered,
job.Openings,
job.Filled
from jobs
left outer join offers on jobs.ID = offers.JobID
join membership.dbo.individuals on jobs.UserID = individuals.ID
join membership.dbo.companies on individuals.CompanyID = companies.ID
where jobs.Hidden = 0
group by offers.JobID,
companies.CommpanyName,
job.Position,
job.Openings,
job.Filled
I've done left outer joins in LINQ before similar to this example but I'm not sure how to combine the count and group statements with this to get the desired result:
CompanyName Position Offered Openings Filled
1 Exmaple Co. Job X 0 2 0
2 Example Co. Job Y 4 6 3
3 Test Co. Job Z 1 1 1
The query is further complicated by the fact that it needs to utilize two separate data contexts. I apologize for the lack of example code, but I'm really not sure how to start this, my LINQ-fu is still weak.
Update:
This is the solution I arrived at with Craig's help, had to use LINQ to Objects because of the unfortunate multiple context setup, JobWithOfferCounts is not an entity object:
IEnumerable<Job> t = context1.JobSet.Include("Offers").Include("Contacts").Where(j => j.Hidden == false);
IEnumerable <JobWithOfferCounts> r = (from j in t
join i in context2.IndividualSet on j.UserID equals i.ID
join c in context2.CompanySet on i.CompanyID equals c.ID
select new JobWithOfferCounts()
{
JobObject = j,
CompanyID = Convert.ToInt32(c.ID),
CompanyName = c.HostName,
OfferCount = j.offers.Count(o => o.Rejected == false),
FilledCount = j.offers.Count(o => o.Accepted == true),
PendingCount = j.offers.Count(o => o.Accepted == false && o.Rejected == false)
});
return r;
I can't see why you have individuals in your query, or why you group by offers.JobID when it (unlike jobs.JobId) could be null, but here's a first stab:
var q = from c in Context.Companies
from i in c.Individuals
from j in i.Jobs
where j.Hidden == 0
select new
{
CompanyName = c.CompanyName,
Position = j.Position,
Offered = j.Offers.Count(),
Openings = j.Openings,
Filled = j.Filled
};
It's rarely correct to use join in LINQ to Entities or LINQ to SQL.