In clause in linq expression - c#

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.

Related

How to write query in Entity Framework with conditional multiple where condition? [duplicate]

This question already has answers here:
Linq: adding conditions to the where clause conditionally
(9 answers)
Closed 3 years ago.
I am creating a wcf application which is connecting to DB to get some data for customer using Entity Framework. The concept is to search a customer based on the search parameters. User can provide all or few or at least one of the search parameters. But I am quite new in Entity Framework and getting confused on how to do this. I can do this in traditional SQL coding by considering If - Else condition in c# side.
This is my code which is getting the all of the paramters:
var customers = from o in natCustomer.CustomerLists
select o;
customers = customers.Where(c => c.Name == sName && c.Age == iAge
&& c.Gender == sGender && c.Height == dHeight && c.Weight == dWeight
&& c.Nationality == sNationality
&& c.EyeColor == sEyeColor && c.SpecialMark == sSpecialMark);
Please help me by suggesting how do I get the result with few or one parameter only.
Thanks
Entity Framework queries are "deferred" queries. They don't actually run until you start asking for results. This means you can build up a query in pieces and it will (mostly) work exactly like one bigger query.
In your case, you can do something like:
var customers = from o in natCustomer.CustomerLists
select o;
if (!string.isNullOrEmpty(sName))
customers = customers.Where(c => c.Name == sName);
if (!string.isNullOrEmpty(sNationality))
customers = customers.Where(c => c.sNationality == sNationality);
if (!string.isNullOrEmpty(SpecialMark ))
customers = customers.Where(c => c.SpecialMark == SpecialMark);
etc. At the end, when you execute the customers query (for example, call ToList or use a foreach loop) EF will consolidate all of those smaller Where clauses into a single SQL query to run against your data.
Assuming you only want to find customers who match on all non-null parameters, an alternative approach is to include the null checks within the where query, and only compare the parameter to the customer data if the parameter is not null.
customers = customers.Where(c => (string.isNullOrEmpty(sName) || c.Name == sName)
&& (iAge == null || c.Age == iAge)
&& (string.isNullOrEmpty(sGender) || c.Gender == sGender));
You need some way to determine if the given inputs are set or not. For a simplification I assume you receive your parameters as nullables. So you could add an additional condition, if the parameter is provided:
customers = sName == null ? customers : customers.Where(c => c.Name == sName);
customers = iAge == null ? customers : customers.Where(c => c.Age == iAge);
customers = sGender == null ? customers : customers.Where(c => c.Gender == sGender);
...

Linq IN Clause in Where

I want to know how to use IN clause in Linq. Here is my Code :-
int empCount = ctx.tblEmpTran
.Count(
e => e.Id == Id &&
e.Month == selectedMonth &&
e.Year == selectedYear &&
e.employeeId.contains()
);
The Following query is supposed to be in IN
SELECT A.Id FROM dbo.EmployeeDetail A WHERE A.CompanyId = 1 AND A.COLS > 0
In the above code, contains method do not popup in intellisense.
This is because you are trying to convert from SQL to Linq, and you couldn't try a worse approach.
You should try to write your LINQ query starting from what you need it to do, forgetting SQL altogether.
In Linq there is no "IN" operator, to achieve the same thing you take your collection and check if it Contains the value.
So in your scenario you should simply generate your collection of valid values and then in your query do:
myCollection.Contains(e.employeeId)
It is "collection CONTAINS value" the logic, not "value is found IN collection". Again if you insist to start from SQL when using Linq you will always incur in this kind of problems.
Check Albahari tutorial on how to approach Linq correctly and your productivity will skyrocket.
You should create a collection of employee IDs that you want to check, and the code would be
employees.contains(e.employeeId)
Instead of this e.employeeId.contains(), you should use this:
listOfIds.Contains(e.employeeId)
where listOfIds would be a list of int, List<int> and would contain the ids you would place between the parentheses after IN(...).
considering that you have a tblEmployeeDetail in the same DbSet and them having a relation through employeeId you can write you query like.
var q = from e in ctx.tblEmployeeDetail where e.Transactions.Any(t => t.Month == selectedMonth &&
t.Year == selectedYear);
int empCount = q.Count();
this is pseudo-code but this is how you would use the LINQ effectively, (Exists is better than In check)

What is lambda equivalent an SQL "in" statement?

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);

How to get invoice ID of settled Executions

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();

Problem with linq query

I have a self referencing table "Product" with the following structure (where D = Draft and A = Approved)
ID ParentID Status Name
---------------------------
1 NULL A Foo
2 1 A Foo2
3 NULL D Bar
4 1 D Foo3
A row can either be "new" (where ParentID == null) or can be a version of an existing row. So we can see from the table that there are 3 versions for the item "Foo" and only 1 for "Bar".
I need a way of returning the latest versions of each item based on whether the user is able to see only "Approved" items or is able to see "Draft" as well. So for example
Users who can see "D" would have:
3 NULL D
4 1 D
The "latest" row for "Foo" and "Bar".
Users who can see "A" would have:
2 1 A
ie. only the "Approved" versions.
Thanks in advance,
Jose
Here is the Linq query that should work for you:
bool hasDraftAccess = false;
var query = DataContext.Records.AsQueryable();
if (!hasDraftAccess) {
query = query.Where(r => r.Status == 'A');
}
var seriesQuery = query.Select(r => new { Record = r, SeriesID = r.ParentID ?? r.ID });
var latestQuery = seriesQuery.GroupBy(s => s.SeriesID).Select(g => g.OrderByDescending(s => s.Record.ID).First());
var resultsQuery = latestQuery.Select(s => s.Record);
var results = resultsQuery.ToArray();
Here's what's happening:
First, add a WHERE clause to filter out draft records if the user doesn't have access to them
Then add a pseudo column called 'SeriesID' that groups all the related versions into that one column. That is, make it easy to group parent and related children.
Group the related records and then pick whichever record is most recent
Select the Linq Entity from the anonymous type so that it is updatable
I should note that if you have the ability to change your data schema you should consider adding a column called InsertDate or something to that effect. Right now I am assuming that whatever record has the highest ID is the latest. It is often better to add a DateTime field and sort on that instead.
I apologize that this isn't actually using Linq syntax--I prefer fluent coding styles--but it could be easily translated to Linq syntax if you preferred it.
Totally untested - but something like this might work, if I've understood the question correctly.
Can see approved
context.Table.Where(p => p.Status == "A")
Can see approved and draft
context.Table.Where(p => p.Status == "D" || (p.Status == "A" && !context.Table.Any(q => q.Status == "D" && q.Parent == p.Parent)))

Categories

Resources