Lets say i have table with the Name Executions like this :
InvoiceID------ExecutionID-------IsSettled
123-----1-----0
123-----2-----1
345-----3-----1
345-----4-----1
567-----5-----0
567-----6-----0
My Question :
What is the query that retrieves only InvoiceIDs where all it's Executions have IsSettled=1.?
I mean the result of the query should be like this:
345-----3-----1
345-----4-----1
i want to execulde any invoices that has any executions with isSettled flog=0,in my question u will find tha invocieID=123 has 2 executions ,one with IsSettled flag=0 and another Execution with Issettled flag=1, so i dont want to include this invoice in my result set as it has one execution with isSettled flag =0
If anyone knows also if I have an Execution Object how can i get the same result using Linq.
The query can be either SQL or LINQ
Thanks
Make a list of invoices Id's that are not settled:
var notNeeded = ExecutionObject.Where(e => e.IsSettled == 0).Select(s => s.InvoiceId).ToList();
Then filter on the invoices that are settled and ensure the invoice id is in the not settled list.
var invoices = ExecutionObject.Where(e => e.IsSettled == 1 && !notNeeded.Contains(e.InvoiceId)).ToList();
The query can be either SQL or LINQ
Query
select * from Executions
where InvoiceID in
(
select InvoiceID from Executions
group by InvoiceID
having min(Issettled)=1
)
SQL FIDDLE
Consider this:
var invoices = (from execution in ExecutionObject
where execution.IsSettled == 1
&& !ExecutionObject.Where(x=>x.IsSettled == 0).Select(y=>y.InvoiceID).Contains(execution.InvoiceID)
select execution.InvoiceID).Distinct().ToList();
I haven't tested it, but the idea is that you filter first by IsSettled == 1 and then remove any that have a record where IsSettled == 0.
It'd be something as simple as the following in linq:
Executions.Where(e => e.IsSettled == 1)
After understanding the question and giving it a go in LinqPad the following Linq query will get what you need:
Executions.GroupBy(e => e.InvoiceId)
.Where(g => g.All(e => e.IsSettled == true))
.SelectMany(g => g)
The linq script is avaliable here: http://share.linqpad.net/fawl6l.linq
If this is a linq query (you haven't told us) then you could use: -
var settled = executions.GroupBy(id => id.invoiceid).Where(inv => inv.All(s => s.issettled)).Select(x => x).ToList();
I think the key point here is you want invoices where there is not a settled = 0?
select distinct InvoiceID
from executions
where invoiceID <> ALL(select invoice_id from executions where is_settled = 0)
or in linq
var q = from i in ctx.Invoices
where ctx.Invoices.All(x => is_settled == 1 || x.invoice_id != i.invoice_id)
select i.invoice_id;
var result = q.Distinct();
Related
i am developing a online test application where have two tables category and subCategory from which i want to select some questions with the help of category and subcategory. something like ( question where category ID in (1) and subcategoryID in (1,2,3,4)
I am getting list of subcategory that is going to pass in query
int[] subCategoryForQuestions=new int[]{1,2,3,4};
var TestDataList = coreDbContext.SolutionMasters
.Where(x => x.CategoryID == categoryID
&& x.DifficultyId == questionLevel
&& subCategoryForQuestions.Contains("here all value in Subcategory"))
.Take(NoOfQuestions);
or something like subcategoryID.contains("some value in array of integer")
can i get some help from anybody?
You could use Contains as per https://blogs.msdn.microsoft.com/alexj/2009/03/25/tip-8-how-to-write-where-in-style-queries-using-linq-to-entities/ and Linq to Entities - SQL "IN" clause .
int[] subCategoryForQuestions=new int[]{1,2,3,4};
var TestDataList = coreDbContext.SolutionMasters
.Where(x => x.CategoryID == categoryID
&& x.DifficultyId == questionLevel
&& subCategoryForQuestions.Contains(x.subcategoryID))
.Take(NoOfQuestions);
This will generate an IN statement behind the scenes. You will want to ensure that the array is relatively small so you don't exhaust the SQL Server parameter limit.
I want to know how many people are in a especify local, using entry and exit validation of this person. If he has entered in the local, then he will generate a transaction with a TrCode = "C0". when he comes out of the place, he will generate a TrCode = "CI". There are other types of TrCode, but it is useless for this kind o validation. i have a query that returns to me this result down bellow:
var query = from a in context.CardDB
join c in context.tblTransaction on a.CardNo equals c.CardNo
where c.TrCode == "C0" || c.TrCode == "CI"
where c.TrSiteCode == sitecode
select c;
Now I have all the rows that have the TrCode == "C0" or TrCode == "CI". But the result gives me all the transactions that the employers(CardDB) did. So the result gives a lot of transactions made of different employers. Sometimes some employer make 2 or even 3 transcations like, when he arrives and when he goes out for lunch, then he cames back etc.
I have to show in a grid just the employers that have in general count more transactions TrCode == "C0" than TrCode == "CI". So, what i have to do to count the transcations of only the employers with the same ID, and, when showing it in the grid, show just a row of this employers and not all the rows.
Since already, Thank you!
var queryNumberC0 = query.Where(c => c.TrCode == "C0").Select(c => c.ID).GroupBy(c => c.Value).ToList();
var queryNumberC1 = query.Where(c => c.TrCode == "C1").Select(c => c.ID).GroupBy(c => c.Value).ToList();
And to get the number of the ID y (Key is the ID of the customer):
int y = [Customer's ID];
int temp = queryNumberC0.Find(c => c.Key == y);
You don't have to specifie the ToList() at the end of the query, do what you want with the result. I just find it easier to browse
I can't figure out a lambda equivalent of this sql statement:
select * from Document
where Document.OrginalDocumentNumber
in (select documentAccess.DocumentId from documentAccess where userId='1')
The problem is that Document & documentaccess tables have no relation to each other.
Any help would be so much appreciated.
Replace IN with EXISTS and you get following:
from d in dbContext.Documents
where dbContext.documentAccesses.Any(
x=>x.DocumentId == d.OrginalDocumentNumber && x.userId == '1' )
select d
Normally, if you have sensible navigation properties, you can avoid join or sub-queries directly:
var documents = from documentAccess in contex.DocumentAccesses
where documentAccess.UserId == 1
select documentAccess.Document;
You may want to use .Distinct() on the results, depending on your data.
Similarly:
var documents = contex.DocumentAccesses
.Where(access => access.UserId == 1)
.Select(access => access.Document);
And even better, if you already have a User in context:
var documents = currentUser.DocumentAccesses.Select(access => access.Document);
I have a situation where I have a Job which has multiple tests which run at specific intervals. A job run generates a unique TestRunId which is a GUID, which is used to reference multiple results, basically grouping a particular run with a unique RunId(GUID).
Now the problem is that I need to select unique runs which have been generated, but my LINQ query picks up every run.
I tried something like this
var testRunIds = ((from tests in context.testresults
where tests.JobId == jobId
select new
{
tests.TestRunId
}).GroupBy(t=>t.TestRunId).OrderBy(t=>t.Key).Skip((pagenum - 1) * pagesize).Take(pagesize)).ToList();
But as I said, this query picks up each and every testResult. Not sure how I do this now. I tried Distinct(), but that too didnt work. Sample data below.
Thanks
I believe the problem is that I have multiple TestRunId values as its essentially a grouping. Inorder to achieve what I need, I tried using (got using Linqer)
from Queries in db.TestResult
where
Queries.JobId == 1
group Queries by new {
Queries.TestRunId,
Queries.StartTime,
Queries.EndTime
} into g
orderby
g.Key.TestRunId
select new {
_ID = (int?)g.Max(p => p.Id),
g.Key.TestRunId,
g.Key.StartTime,
g.Key.EndTime
}
But this works only for MSSQL datasource which is essentially a
SELECT max(id)[ ID],
TestRunId,
StartTime,
Endtime
FROM dbo.query where jobid = 1 group by TestRunId,StartTime,Endtime order by StartTime;
But what I need is
SELECT TestRunId,StartTime,Endtime FROM testresult where jobid = 1 group by TestRunId order by StartTime;
for MySQL.
Try this:-
var jobs = context.testresults;
var query2 = jobs.Where(x => x.TestID == 1).OrderBy(x => x.StartTime).Select(x => x.TestRunID).Distinct();
Working Fiddle.
I think you're possibly looking for this:
var testRunIds = context.testresults.Where(t => t.JobId == jobId).OrderBy(t => t.starttime)
.Select(t => t.TestRunId).Distinct().Skip((pagenum - 1) * pagesize).Take(pagesize)
.ToList();
Do the filtering and ordering first, then select the single field needed, then use Distinct() for uniqueness, then skip/take as required. Selecting the single field first then attempting to order or filter on other fields in the table won't work as those fields are no longer part of the query.
Thanks for helping me out. I managed to do this in a two step process.
var testRunIds = (from tests in context.testresults
where tests.JobId == jobId
select new
{
tests.TestRunId,
tests.StartTime
}).OrderBy(x => x.StartTime).Skip((pagenum - 1) * pagesize).Take(pagesize).GroupBy(x=>x.TestRunId).ToList();
var resultData = testRunIds.Select(testRunId => (context.testresults.Where(
items => items.TestRunId == testRunId.Key)).FirstOrDefault()).ToList();
I have 2 SQL statements that basically do the same thing, that is, retrieve the last record from a table based on a datetime field for a group of records. I am using the data-first Entity Framework model. How would I write either of these SQL statements using LINQ Lambda functions?
ie,
var u = db.AccessCodeUsage.Where(...).GroupBy(...)
rather than
var u = from a in db.AccessCodeUsage
where ...
group by ...
SQL Statements:
SELECT *
FROM AccessCodeUsage a
WHERE NOT EXISTS (SELECT 1
FROM AccessCodeUsage
WHERE LocationId = a.LocationId
AND Timestamp > a.Timestamp)
SELECT a.*
FROM AccessCodeUsage a
WHERE a.Timestamp =
(SELECT MAX(Timestamp)
FROM AccessCodeUsage
WHERE a.LocationId = LocationId
AND a.AccessCode = AccessCode
GROUP By LocationId, AccessCode)
If you need to have the method-call form, but are finding it tricky to work out, then use the other syntax first:
from a in db.AccessCodeUsage
orderby a.TimeStamp descending
group a by a.LocationId into grp
from g in grp select g.First();
Then convert to method calls by taking each clause one at a time:
db.AccessCodeUsage
.OrderByDescending(a => a.TimeStamp)
.GroupBy(a => a.LocationId)
.Select(g => g.First());
From which I can workout the second without bothering to write out the linq-syntax form first:
db.AccessCodeUsage
.OrderByDescending(a => a.TimeStamp)
.GroupBy(a => new {a.LocationId, a.AccessCode})
.Select(g => g.First());
(Except it doesn't include what may be a bug, in that if timestamps aren't guaranteed unique, the SQL given in the question could include some extra inappropriate results).
I can't check on the SQL produced right now, but it should hopefully be equivalent in results (if not necessarily matching). There's cases where grouping doesn't translate to SQL well, but I certainly don't think this would be one.
I ended up using the following which corresponds to the first SQL statement.
// Retrieve only the latest (greatest value in timestamp field) record for each Access Code
var last = AccessCodeUsages.Where(u1 => !AccessCodeUsages
.Any(u2 => u2.LocationId == u1.LocationId &&
u2.AccessCode == u1.AccessCode &&
u2.Timestamp > u1.Timestamp));