Simple Example Subquery Linq
Simple answer is use the "let" keyword and generate a sub-query that supports your conditional set for the main entity.
var usersEnrolledInCourses = from u in User_Users
let ces = from ce in Course_Enrollments
select ce.UserID
where ces.Contains(u.UserID)
select u;
This will create an exists block in TSQL similar to
SELECT [Extent1].*
FROM dbo.User_Users AS Extent1
WHERE EXISTS (SELECT 1 AS [C1]
FROM dbo.Course_Enrollements AS Extent2
WHERE (Extent2.UserID = Extent1.UserId))
It's close to what you've asked for and will generally create the same query plan on SQL Server.
Hope this helps!
How to do a subquery in LINQ?
Here's a subquery for you!
List<int> IdsToFind = new List<int>() {2, 3, 4};
db.Users
.Where(u => SqlMethods.Like(u.LastName, "%fra%"))
.Where(u =>
db.CompanyRolesToUsers
.Where(crtu => IdsToFind.Contains(crtu.CompanyRoleId))
.Select(crtu => crtu.UserId)
.Contains(u.Id)
)
Regarding this portion of the question:
predicateAnd = predicateAnd.And(c => c.LastName.Contains(
TextBoxLastName.Text.Trim()));
I strongly recommend extracting the string from the textbox before authoring the query.
string searchString = TextBoxLastName.Text.Trim();
predicateAnd = predicateAnd.And(c => c.LastName.Contains( searchString));
You want to maintain good control over what gets sent to the database. In the original code, one possible reading is that an untrimmed string gets sent into the database for trimming - which is not good work for the database to be doing.
LINQ subquery IN
var innerquery = from x in context.DataDictVal
where x.TbiTableName == myTableNameVariable
&& x.DdColumnName == "Status"
&& x.DdbColumnValLangDsc1.StartsWith("ac")
select x.DdvColumnVal;
var query = from c in context.Client
where innerquery.Contains(c.Etat)
select c;
LINQ TO SQL Subquery
This should work for you:-
var result = (from x in
((from data in db.DATA orderby data.ID descending select data).Take(2))
orderby x.ID
select x).FirstOrDefault();
Subquery in Where Clause of LINQ statement
I think a simple join would do the job. It will filter out the 'cheques' that have no relative 'app':
var _entitylist =
from cheque in context.postDatedCheques
join app in context.applications on cheque.appSancAdvice.application equals app
select cheque;
Edit:
Solutions using a .Contains(...)
will be translated into a SQL IN
statement. Which will be very inefficient. Linq join
is translated into SQL INNER JOIN
which is very efficient if your DB schema is well trimmed (FKs, index)
LINQ how to translate subquery in FROM clause
What may help is going through a couple sample linq queries and look at the results. For example, the following code will create an IEnumerable of val1's.
var subSelect1 = (from val1 in aTable
where val1.foo = "bar"
);
Note the above is equivalent to the below.
var subSelect1 = (from val1 in aTable
where val1.foo = "bar"
select val1 /* this select statement is implied in the above */
);
Adding the select new {val1.foobar} after the where clause creates an IEnumerable of an anonymous type, with one property named foobar. This means that you'll only be able to join against the one property foobar.
var subSelect1 = (from val1 in aTable
where val1.foo == "bar"
select new {val1.foobar}
);
var mainSelect = (from f in subSelect1
where f.foobar == "test")
By leaving out the select new, you'll have access to all the fields in val1.
var subSelect1 = (from val1 in aTable
where val1.foo == "bar"
);
var mainSelect = (from v in subSelect1
where v.foobar == "test"
and v.bar == "status"
)
How to use GroupBy() in subqueries with LINQ?
Error message says that you have to include Id
column in projection. But you can't do that with GroupBy
. So rewrite query into two steps (removed not needed includes):
var rawRecords = UnitOfWork.FreeBets
.Where(f => f.FreeBetCards.Any(cards => cards.UserId == request.UserId))
.Select(f => new
{
FreeBetId = f.FreeBetId
LineCategories = f.FreeBetCategories.Select(c => new { c.Id, c.LineCategoryID, c.Title })
.ToList()
})
.AsEnumerable();
var records = rawRecords
.Select(f => new FreeBetDTO
{
FreeBetId = f.FreeBetId
LineCategories = f.LineCategories.GroupBy(g => new { g.LineCategoryID, g.Title })
.Select(c =>
new LineCategoryDTO
{
LineCategoryID = c.Key.LineCategoryID,
Title = c.Key.Title
})
});
Similar query, but more optimal:
var query =
from f in UnitOfWork.FreeBets
from c in f.FreeBetCards
where f.FreeBetCards.Any(cards => cards.UserId == request.UserId)
select new { f.FreeBetId, c.LineCategoryID, c.Title };
query = query.Distinct();
var records = query.AsEnumerable()
.GroupBy(f => f.FreeBetId)
.Select(g => new FreeBetDTO
{
FreeBetId = g.Key
LineCategories = g.Select(c =>
new LineCategoryDTO
{
LineCategoryID = c.LineCategoryID,
Title = c.Title
})
.AsEnumerable()
});
SQL Server query with subquery to LINQ query
This won't be the same SQL but it should produce the same result in memory:
var ytdClosureRateData = _context.EvaluationHistoryTable
.Where(t => t.InsertDate.Value.Year == DateTime.Now.Year)
.GroupBy(m => new
{
Month = m.InsertDate.Value.Month
})
.Select(g => new
{
Month = g.Key.Month,
ItemCount = g.Count(),
ClosedCount = g.Where(t => t.TicketStatus == "CLOSED").Count()
}).OrderBy(a => a.MonthNumber)
.ToList()
.Select(x => new YtdTicketClosureRateModel
{
MonthName = DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(x.Month),
MonthNumber = x.Month,
ItemCount = x.ItemCount,
ClosedCount = x.ClosedCount,
ClosureRate = x.ClosedCount * 100D / x.ItemCount
})
.ToList();
Two techniques have been implemented here:
Use Fluent Query to specify the filter to apply for the ClosedCount set, you can combine Fluent and Query syntax to your hearts content, they each have pros and cons, in this instance it just simplifed the syntax to do it this way.
Focus the DB query on only bringing back the data that you need, the rest can be easily calculated in member after the initial DB execution. That is why there are 2 projections here, the first should be expressed purely in SQL, the rest is evaluated as Linq to Objects
The general assumption is that traffic over the wire and serialization are generally the bottle necks for simple queries like this, so we force Linq to Entities (or Linq to SQL) to produce the smallest payload that is practical and build the rest or the values and calculations in memory.
UPDATE:
Svyatoslav Danyliv makes a really good point in this answer
The logic can be simplified, from both an SQL and LINQ perspective by using a CASE
expression on the TicketStatus
to return 1
or 0
and then we can simply sum that column, which means you can avoid a nested query and can simply join on the results.
Writing a subquery using LINQ in C#
Although it doesn't answer your question directly, what you are trying to do is much better suited for an inner join:
SELECT *
FROM SectionDataTable S1
INNER JOIN SectionDataTable S2 ON S1.CourseID = S2.CourseID
WHERE S2.SectionID = iSectionID
This then could be modeled very similarily using linq:
var query = from s1 in SectionDataTable
join s2 in SectionDataTable
on s1.CourseID equals s2.CourseID
where s2.SectionID == iSectionID
select s1;
Related Topics
C# Generics Compared to C++ Templates
How to Set PDF Paragraph or Font Line-Height with Itextsharp
With C# Use Chrome to Covert HTML to Pdf
How to Convert Code from C# to PHP
Calling an Overridden Method from a Parent Class Ctor
Convert from Word Document to HTML
How to Change The Colour of The Line Below/Border of a Textbox (Entry)
Auto Create Database Tables from Objects, Entity Framework
Duplicate Key Exception from Entity Framework
How to Get the Value of a Session Variable Inside a Static Method
How to Prevent Xss (Cross Site Scripting) Whilst Allowing HTML Input
Benefits of Use Parameters Instead of Concatenation
SQL Server Blocked Access to Procedure 'Sys.Sp_Oacreate' of Component 'Ole Automation Procedures'
Linq: How to Exclude Condition If Parameter Is Null
Perform Button Click Event When User Press Enter Key in Textbox
How to Add a Local Script File to The HTML of a Webbrowser Control