0% found this document useful (0 votes)
16 views

Entity Framework

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Entity Framework

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 25

Entity Framework

What is LINQ?
LINQ (Language Integrated Query) is uniform query syntax in C# and VB.NET to
retrieve data from different sources and formats. It is integrated in C# or VB,
thereby eliminating the mismatch between programming languages and
databases, as well as providing a single querying interface for different types of
data sources.

For example, SQL is a Structured Query Language used to save and retrieve
data from a database. In the same way, LINQ is a structured query syntax built
in C# and VB.NET to retrieve data from different types of data sources such as
collections, ADO.Net DataSet, XML Docs, web service and MS SQL Server and
other databases.

LINQ Usage

LINQ queries return results as objects. It enables you to uses object-oriented


approach on the result set and not to worry about transforming different
formats of results into objects.

The following example demonstrates a simple LINQ query that gets all strings
from an array which contains 'a'.
using System;
using System.Linq;

public class Program


{
public static void Main()
{
// Data source
string[] names = {"Bill", "Steve", "James", "Mohan" };

// LINQ Query
var myLinqQuery = from name in names
where name.Contains('a')
select name;

// Query execution
foreach (var name in myLinqQuery)
Console.Write(name + " ");
}
}

Let keyword
The 'let' keyword is useful in query syntax. It projects a new range variable,
allows re-use of the expression and makes the query more readable.

For example, you can compare string values and select the lowercase string
value as shown below:

var lowercaseStudentNames = from s in studentList where


s.StudentName.ToLower().StartsWith("r") select s.StudentName.ToLower();

LINQ - into Keyword


Use into keyword in LINQ query to form a group or to continue a query after a
select clause.

var teenAgerStudents = from s in studentList

where s.Age > 12 && s.Age < 20

select s
into teenStudents

where teenStudents.StudentName.StartsWith("B")

select teenStudents;

In the above query, the 'into' keyword introduced a new range variable
teenStudents, so the first range variable s goes out of scope. You can write a
further query after the into keyword using a new range variable.

Entity Framework - Database Operations

The DbContext API in your applications is used as a bridge between your classes and your
database. The DbContext is one of the most important classes in the Entity Framework.
● It enables to express and execute queries.
● It takes query results from the database and transforms them into instances of our model
classes.
● It can keep track of changes to entities, including adding and deleting, and then triggers the
creation of insert, update and delete statements that are sent to the database on demand.
Following are the domain ad context classes on which we will be performing different operations
in this chapter. This is the same example which we have created in the chapater, Database First
Approach.

Context Class Implementation


using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;

namespace DatabaseFirstDemo {

public partial class UniContextEntities : DbContext {

public UniContextEntities(): base("name = UniContextEntities") {}

protected override void OnModelCreating(DbModelBuilder modelBuilder)


{
throw new UnintentionalCodeFirstException();
}

public virtual DbSet<Course> Courses { get; set; }


public virtual DbSet<Enrollment> Enrollments { get; set; }
public virtual DbSet<Student> Students { get; set; }
}
}

Standard Query Operators


Standard Query Operators in LINQ are actually extension methods for the
IEnumerable<T> and IQueryable<T> types. They are defined in the
System.Linq.Enumerable and System.Linq.Queryable classes. There are
over 50 standard query operators available in LINQ that provide different
functionalities like filtering, sorting, grouping, aggregation, concatenation, etc.

Standard Query Operators in Query Syntax

Standard Query Operators in


Query Syntax

Standard Query Operators in Method Syntax

Standa
rd Query Operators in Method Syntax

Standard query operators in query syntax is converted into extension methods


at compile time. So both are same.

Standard Query Operators can be classified based on the functionality they


provide. The following table lists all the classification of Standard Query
Operators:

Classification Standard Query Operators


Filtering Where, OfType

Sorting OrderBy, OrderByDescending, ThenBy, ThenByDescending, Reverse

Grouping GroupBy, ToLookup

Join GroupJoin, Join

Projection Select, SelectMany

Aggregation Aggregate, Average, Count, LongCount, Max, Min, Sum

Quantifiers All, Any, Contains

Elements ElementAt, ElementAtOrDefault, First, FirstOrDefault, Last, LastOrDefault,


Single, SingleOrDefault

Set Distinct, Except, Intersect, Union

Partitioning Skip, SkipWhile, Take, TakeWhile

Concatenation Concat

Equality SequenceEqual

Generation DefaultEmpty, Empty, Range, Repeat

Conversion AsEnumerable, AsQueryable, Cast, ToArray, ToDictionary, ToList

Create Operation
Adding a new object with Entity Framework is as simple as constructing a new instance of your
object and registering it using the Add method on DbSet. The following code lets you add a new
student to the database.
class Program {

static void Main(string[] args) {

var newStudent = new Student();

//set student name

newStudent.FirstMidName = "Bill";
newStudent.LastName = "Gates";
newStudent.EnrollmentDate = DateTime.Parse("2015-10-21");
newStudent.ID = 100;

//create DBContext object

using (var dbCtx = new UniContextEntities()) {

//Add Student object into Students DBset


dbCtx.Students.Add(newStudent);

// call SaveChanges method to save student into database


dbCtx.SaveChanges();
}
}
}

Update Operation
Changing existing objects is as simple as updating the value assigned to the property(s) you want
changed and calling SaveChanges. For example, the following code is used to change the last
name of Ali from Khan to Aslam.
using (var context = new UniContextEntities()) {

var student = (from d in context.Students where d.FirstMidName == "Ali"


select d).Single();
student.LastName = "Aslam";
context.SaveChanges();
}

Delete Operation
To delete an entity using Entity Framework, you use the Remove method on DbSet. Remove
works for both existing and newly added entities. Calling Remove on an entity that has been
added but not yet saved to the database will cancel the addition of the entity. The entity is
removed from the change tracker and is no longer tracked by the DbContext. Calling Remove on
an existing entity that is being change-tracked will register the entity for deletion the next time
SaveChanges is called. The following example is of a code where the student is removed from
the database whose first name is Ali.
using (var context = new UniContextEntities()) {
var bay = (from d in context.Students where d.FirstMidName == "Ali"
select d).Single();
context.Students.Remove(bay);
context.SaveChanges();
}

Read Operation
Reading the existing data from the database is very simple. Following is the code in which all the
data from the Student table are retrieved and then a program will be displayed with the students’
first and last name in alphabetical order.
using (var db = new UniContextEntities()) {
var query = from b in db.Students orderby b.FirstMidName select b;
Console.WriteLine("All All student in the database:");

foreach (var item in query) {


Console.WriteLine(item.FirstMidName +" "+ item.LastName);
}

Console.WriteLine("Press any key to exit...");


Console.ReadKey();
}

DbSet in Entity Framework 6


The DbSet class represents an entity set that can be used for create, read, update,
and delete operations.

The context class (derived from DbContext) must include the DbSet type properties
for the entities which map to database tables and views.
We will be learning how to migrate changes into the database when there are multiple DbContext
classes in the application.
● Multiple DbContext was first introduced in Entity Framework 6.0.
● Multiple context classes may belong to a single database or two different databases.
In our example, we will define two Context classes for the same database. In the following code,
there are two DbContext classes for Student and Teacher.

Let’s take a look into the following example where multiple operations are performed
in a single transaction. The code is as −
class Program {

static void Main(string[] args) {

using (var context = new UniContextEntities()) {

using (var dbContextTransaction =


context.Database.BeginTransaction()) {

try {

Student student = new Student() {


ID = 200,
FirstMidName = "Ali",
LastName = "Khan",
EnrollmentDate = DateTime.Parse("2015-12-1")
};

context.Students.Add(student);

context.Database.ExecuteSqlCommand(@"UPDATE Course SET Title


=
'Calculus'" + "WHERE CourseID = 1045");

var query = context.Courses.Where(c ⇒ c.CourseID == 1045);

foreach (var item in query) {


Console.WriteLine(item.CourseID.ToString()
+ " " + item.Title + " " + item.Credits);
}

context.SaveChanges();
var query1 = context.Students.Where(s ⇒ s.ID == 200);

foreach (var item in query1) {


Console.WriteLine(item.ID.ToString()
+ " " + item.FirstMidName + " " + item.LastName);
}
dbContextTransaction.Commit();
} catch (Exception) {
dbContextTransaction.Rollback();
}

}
}
}
}
● Beginning a transaction requires that the underlying store connection is open.
● So calling Database.BeginTransaction() will open the connection, if it is not already opened.
● If DbContextTransaction opened the connection then it will close it when Dispose() is
called.

LINQ Query Syntax:

using (var ctx = new SchoolDBEntities())


{
var student = (from s in ctx.Students
where s.StudentName == "Bill"
select s).FirstOrDefault<Student>();
}

LINQ Method Syntax:

using (var ctx = new SchoolDBEntities())


{
var student = ctx.Students
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}

Entity Framework - Table-Valued Function


https://www.tutorialspoint.com/entity_framework/entity_framework_stored_procedures.htm

let us learn how to map Table-valued Functions (TVFs) using the Entity Framework Designer and
how to call a TVF from a LINQ query.
●TVFs are currently only supported in the Database First workflow.
●It was first introduced in Entity Framework version 5.
●To use the TVFs you must target .NET Framework 4.5 or above.
●It is very similar to stored procedures but with one key difference, i.e., the result of a TVF is
composable. This means the results from a TVF can be used in a LINQ query while the
results of a stored procedure cannot.
class Program {

static void Main(string[] args) {

using (var context = new UniContextEntities()) {

var CourseID = 4022;

// Return all the best students in the Microeconomics class.


var students = context.GetStudentGradesForCourse(CourseID);

foreach (var result in students) {


Console.WriteLine("Student ID: {0}, Grade: {1}",
result.StudentID, result.Grade);
}

Console.ReadKey();
}
}
}

Asynchronous Querying and Saving in EF 6


Asynchronous execution has been introduced in .NET 4.5 which can be useful in Entity
Framework. EF 6 allows us to execute a query and command asynchronously using an
instance of DbContext.

Let's see how to execute asynchronous queries first and then, we will see an
asynchronous call to context.SaveChanges.

Asynchronous Query
The following is an example of the async method which executes a LINQ-to-Entity
query asynchronously and returns the result.

private static async Task<Student> GetStudent()


{
Student student = null;
using (var context = new SchoolDBEntities())
{
Console.WriteLine("Start GetStudent...");

student = await (context.Students.Where(s => s.StudentID ==


1).FirstOrDefaultAsync<Student>());

Console.WriteLine("Finished GetStudent...");
}

return student;
}

As you can see in the above code, the GetStudent() method is marked with the
async keyword, which makes it an asynchronous method. The return type of the
asynchrounous method must be Task<T>. The GetStudent() method returns an
object of the Student entity, so return type must be of Task<Student> type.

Also, the LINQ query is marked with the await keyword. This frees up the calling
thread to execute other code until it executes the query and returns the result. We
have used the FirstOrDefaultAsync async extension method to get the result. You
may use other async methods appropriately such as SingleOrDefaultAsync,
ToListAsyn etc.

Asynchronous Save
EF API provides the SaveChangesAsync() method to save entities to the database
asynchronously. The following SaveStudent method saves the Student entity to the
database asynchronously.

private static async Task SaveStudent(Student editedStudent)


{
using (var context = new SchoolDBEntities())
{
context.Entry(editedStudent).State = EntityState.Modified;

Console.WriteLine("Start SaveStudent...");

int x = await (context.SaveChangesAsync());

Console.WriteLine("Finished SaveStudent...");
}
}

Getting the async Query Result


The following example demonstrates executing an async query, getting the result and
saving the modified entity.

public static void AsyncQueryAndSave()


{
var query = GetStudent();

Console.WriteLine("Do something else here till we get the query


result..");

query.Wait();

var student = query.Result;

student.FirstName = "Steve";

var numOfSavedStudent = SaveStudent(student);

Console.WriteLine("Do something else here till we save a student.." );

studentSave.Wait();

Console.WriteLine("Saved Entities: {0}", numOfSavedStudent.Result);


}

Output
Start GetStudent...

Do something else here till we get the query result..

Finished GetStudent...

Start SaveStudent...

Do something else here till we save a student..

Finished SaveStudent...

Saved Entities: 1
In the above example, the async method GetStudent() is called and it stores the
reference in the query variable. This will start to execute the GetStudent() method,
but frees the calling thread, so that it can execute further statements in the
AsyncQueryAndSave method. The query.wait() method holds the execution until the
asynchronous method completes. Once it completes, we can get the result using the
variable query.Result. In the same way, the asynchronous save method is called and
gets the result.

Add or Remove Multiple Entities in Entity Framework


https://www.entityframeworktutorial.net/entityframework6/addrange-
removerange.aspx

Entity Framework 6 introduced methods to add and remove a collection of entities in


one go. The DbSet.AddRange() method attaches a collection of entities to the context
with Added state, which will execute the INSERT command in the database for all
entities on SaveChanges(). In the same way, the DbSet.RemoveRange() method
attaches a collection of entities with Deleted state, which in turn will execute the
DELETE command for all entities on SaveChanges().

Adding or removing entities using the AddRange and RemoveRange methods improves
the performance. It is recommended to use these methods if you want to insert or
delete large number of records from the database using Entity Framework.

The following example demonstrates saving multiple entities.

IList<Student> newStudents = new List<Student>() {


new Student() { StudentName =
"Steve" };
new Student() { StudentName = "Bill" };
new Student() { StudentName =
"James" };
};

using (var context = new SchoolDBEntities())


{
context.Students.AddRange(newStudents);
context.SaveChanges();
}

The following example demonstrates removing multiple entities.

IList<Student> studentsToRemove = new List<Student>() {


new Student() { StudentId = 1,
StudentName = "Steve" };
new Student() { StudentId = 2,
StudentName = "Bill" };
new Student() { StudentId = 3,
StudentName = "James" };
};

using (var context = new SchoolDBEntities())


{
context.Students.RemoveRange(studentsToRemove);
context.SaveChanges();
}

Note: EF Core improves the performance of AddRange and RemoveRange methods by


executing the INSERT and DELETE commands for all entities in a single database
round trip.

Linq-to-Entities Query
Here, you will learn how to write LINQ-to-Entities queries and get the result in Entity
Framework 6.x as well as in Entity Framework Core. Visit LINQ Tutorials to learn LINQ
step by step.

The DbSet class is derived from IQuerayable. So, we can use LINQ for querying
against DbSet, which will be converted to an SQL query. EF API executes this SQL
query to the underlying database, gets the flat result set, converts it into appropriate
entity objects and returns it as a query result.

The following are some of the standard query operators (or extension methods) that
can be used with LINQ-to-Entities queries.

LINQ Extension Methods

First()

FirstOrDefault()

Single()

SingleOrDefault()

ToList()

Count()

Min()

Max()

Last()

LastOrDefault()

Average()

Find()
In addition to LINQ extension methods, we can use the Find() method of DbSet to
search the entity based on the primary key value.

Let's assume that SchoolDbEntities is our DbContext class and Students is the
DbSet property.

var ctx = new SchoolDBEntities();


var student = ctx.Students.Find(1);
In the above example, ctx.Student.Find(1) returns a student record whose
StudentId is 1 in the database. If no record is found, then it returns null. The above
query will execute the following SQL query.

SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]
WHERE [Extent1].[StudentId] = @p0',N'@p0 int',@p0=1
go

First/FirstOrDefault
If you want to get a single student object, when there are many students, whose
name is "Bill" in the database, then use First or FirstOrDefault, as shown below:

LINQ Query Syntax:

using (var ctx = new SchoolDBEntities())


{
var student = (from s in ctx.Students
where s.StudentName == "Bill"
select s).FirstOrDefault<Student>();
}

LINQ Method Syntax:

using (var ctx = new SchoolDBEntities())


{
var student = ctx.Students
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}

EF 6 executes the following SQL query in the database for the above LINQ query.

SELECT TOP (1)


[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]
WHERE 'Bill' = [Extent1].[StudentName]

EF Core executes the following query in the database.

SELECT TOP (1)


[s].[StudentId], [s].[DoB], [s].[FirstName], [s].[GradeId],
[s].[LastName], [s].[MiddleName]
FROM [Students] AS [s]
WHERE [s].[FirstName] = N'Bill'
ADVERTISEMENT

Parameterized Query
EF builds and executes a parameterized query in the database if the LINQ-to-Entities
query uses parameters, such as below.

using (var ctx = new SchoolDBEntities())


{
string name = "Bill";
var student = ctx.Students
.Where(s => s.StudentName == name)
.FirstOrDefault<Student>();
}

The above query will result into the following SQL query in EF 6.

SELECT TOP (1)


[Extent1].[StudentId] AS [StudentId],
[Extent1].[Name] AS [Name]
FROM [dbo].[Student] AS [Extent1]
WHERE ([Extent1].[Name] = @p__linq__0) OR (([Extent1].[Name] IS NULL)
AND (@p__linq__0 IS NULL))',N'@p__linq__0
nvarchar(4000)',@p__linq__0=N'Bill'

The difference between First and FirstOrDefault is that First() will throw an
exception if there is no result data for the supplied criteria, whereas
FirstOrDefault() returns a default value (null) if there is no result data.

ToList
The ToList method returns the collection result. If you want to list all the students
with the same name then use ToList():

using (var ctx = new SchoolDBEntities())


{
var studentList = ctx.Students.Where(s => s.StudentName ==
"Bill").ToList();
}

We may also use ToArray, ToDictionary or ToLookup. The above query would result in
the following database query:

SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]
WHERE 'Bill' = [Extent1].[StudentName]
go

GroupBy
Use the group by operator or GroupBy extension method to get the result based on
the group by the particular property of an entity.

The following example gets the results grouped by each Standard. Use the foreach
loop to iterate the group.

LINQ Query Syntax:

using (var ctx = new SchoolDBEntities())


{
var students = from s in ctx.Students
group s by s.StandardId into studentsByStandard
select studentsByStandard;

foreach (var groupItem in students)


{
Console.WriteLine(groupItem.Key);

foreach (var stud in groupItem)


{
Console.WriteLine(stud.StudentId);
}

}
}

LINQ Method Syntax:

using (var ctx = new SchoolDBEntities())


{
var students = ctx.Students.GroupBy(s => s.StandardId);

foreach (var groupItem in students)


{
Console.WriteLine(groupItem.Key);

foreach (var stud in groupItem)


{
Console.WriteLine(stud.StudentId);
}

}
}

The above query will execute the following database query:

SELECT
[Project2].[C1] AS [C1],
[Project2].[StandardId] AS [StandardId],
[Project2].[C2] AS [C2],
[Project2].[StudentID] AS [StudentID],
[Project2].[StudentName] AS [StudentName],
[Project2].[StandardId1] AS [StandardId1]
FROM ( SELECT
[Distinct1].[StandardId] AS [StandardId],
1 AS [C1],
[Extent2].[StudentID] AS [StudentID],
[Extent2].[StudentName] AS [StudentName],
[Extent2].[StandardId] AS [StandardId1],
CASE WHEN ([Extent2].[StudentID] IS NULL) THEN CAST(NULL AS int) ELSE 1
END AS [C2]
FROM (SELECT DISTINCT
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1] ) AS [Distinct1]
LEFT OUTER JOIN [dbo].[Student] AS [Extent2] ON ([Distinct1].
[StandardId] = [Extent2].[StandardId]) OR (([Distinct1].[StandardId] IS
NULL) AND ([Extent2].[StandardId] IS NULL))
) AS [Project2]
ORDER BY [Project2].[StandardId] ASC, [Project2].[C2] ASC
go

OrderBy
Use the OrderBy operator with ascending/descending keywords in LINQ query syntax
to get the sorted entity list.

using (var ctx = new SchoolDBEntities())


{
var students = from s in ctx.Students
orderby s.StudentName ascending
select s;
}

Use the OrderBy or OrderByDescending method to get the sorted entity list.

using (var ctx = new SchoolDBEntities())


{
var students = ctx.Students.OrderBy(s => s.StudentName).ToList();
// or descending order
var descStudents = ctx.Students.OrderByDescending(s =>
s.StudentName).ToList();
}

The above query will execute the following database query:

SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent1].[StandardId] AS [StandardId]
FROM [dbo].[Student] AS [Extent1]
ORDER BY [Extent1].[StudentName] ASC
go
ADVERTISEMENT

Anonymous Object Result


LINQ-to-Entities queries do not always have to return entity objects. We may choose
some of the properties of an entity as a result.

The following query returns a list of anonymous objects which contains StudentId and
StudentName properties.

LINQ Query Syntax:

using (var ctx = new SchoolDBEntities())


{
var anonymousObjResult = from s in ctx.Students
where s.StandardId == 1
select new {
Id = st.StudentId,
Name = st.StudentName
};

foreach (var obj in anonymousObjResult)


{
Console.Write(obj.Name);
}
}

LINQ Method Syntax:

using (var ctx = new SchoolDBEntities())


{
var anonymousObjResult = ctx.Students
.Where(st => st.Standard == 1)
.Select(st => new {
Id = st.StudentId,
Name = st.StudentName });

foreach (var obj in anonymousObjResult)


{
Console.Write(obj.Name);
}
}

The above query will execute the following database query:

SELECT
[s].[StudentID] AS [Id], [s].[StudentName] AS [Name]
FROM [Student] AS [s]
WHERE [s].[StandardId] = 1
go
The projectionResult in the above query will be the anonymous type, because there is
no class/entity which has these properties. So, the compiler will mark it as
anonymous.

Nested queries
You can also execute nested LINQ-to-entity queries as shown below:

The nested query shown above will result in an anonymous list with a StudentName
and Course object.

SELECT
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Join1].[CourseId1] AS [CourseId],
[Join1].[CourseName] AS [CourseName],
[Join1].[Location] AS [Location],
[Join1].[TeacherId] AS [TeacherId]
FROM [dbo].[Student] AS [Extent1]
INNER JOIN (SELECT [Extent2].[StudentId] AS [StudentId],
[Extent3].[CourseId] AS [CourseId1], [Extent3].[CourseName] AS
[CourseName],
[Extent3].[Location] AS [Location], [Extent3].[TeacherId] AS
[TeacherId]
FROM [dbo].[StudentCourse] AS [Extent2]
INNER JOIN [dbo].[Course] AS [Extent3]
ON [Extent3].[CourseId] = [Extent2].[CourseId] ) AS [Join1]
ON [Extent1].[StudentID] = [Join1].[StudentId]
WHERE 1 = [Extent1].[StandardId]
go

Sample LINQ Queries


https://www.tutorialsteacher.com/linq/sample-linq-queries
In this section, you will learn some complex LINQ queries. We will use the
following Student and Standard collection for our queries.

Sample Collections:
IList<Student> studentList = new List<Student>() { new Student()
{ StudentID = 1, StudentName = "John", Age = 18, StandardID = 1 } , new
Student() { StudentID = 2, StudentName = "Steve", Age = 21, StandardID =
1 } , new Student() { StudentID = 3, StudentName = "Bill", Age = 18,
StandardID = 2 } , new Student() { StudentID = 4, StudentName = "Ram" ,
Age = 20, StandardID = 2 } , new Student() { StudentID = 5, StudentName
= "Ron" , Age = 21 } }; IList<Standard> standardList = new
List<Standard>() { new Standard(){ StandardID = 1,
StandardName="Standard 1"}, new Standard(){ StandardID = 2,
StandardName="Standard 2"}, new Standard(){ StandardID = 3,
StandardName="Standard 3"} };

Multiple Select and where operator


Example: Multiple Select and where Operator
var studentNames = studentList.Where(s => s.Age > 18) .Select(s =>
s) .Where(st => st.StandardID > 0) .Select(s => s.StudentName);
Try it
Output:
Steve
Ram

The following query returns Enumerable of anonymous object that has only
StudentName property:

Example: LINQ Query returns Collection of Anonymous Objects


var teenStudentsName = from s in studentList where s.age > 12 && s.age <
20 select new { StudentName = s.StudentName };
teenStudentsName.ToList().ForEach(s =>
Console.WriteLine(s.StudentName));
Try it
Output:
John
Bill

Group By
The following query returns list students group by StandardID:

Example: LINQ GroupBy Query - C#


var studentsGroupByStandard = from s in studentList group s by
s.StandardID into sg orderby sg.Key select new { sg.Key, sg }; foreach
(var group in studentsGroupByStandard) { Console.WriteLine("StandardID
{0}:", group.Key); group.sg.ToList().ForEach(st =>
Console.WriteLine(st.StudentName )); }
Try it
Output:
StandardID 0:
Ron
StandardID 1:
John
Steve
StandardID 2:
Bill
Ram

The output includes Ron who doesn't have any StandardID. So Ron falls under
StandardID 0.

To remove a student who doesn't have a StandardID, use a where operator


before the group operator:

Example: LINQ GroupBy Query - C#


var studentsGroupByStandard = from s in studentList where s.StandardID >
0 group s by s.StandardID into sg orderby sg.Key select new { sg.Key, sg
};
Try it
Output:
StandardID 1:00.333333333333333
John
Steve
StandardID 2:
Bill
Ram
ADVERTISEMENT

Left outer join


Use left outer join to display students under each standard. Display the
standard name even if there is no student assigned to that standard.

Example: LINQ Left Outer Join - C#


var studentsGroup = from stad in standardList join s in studentList on
stad.StandardID equals s.StandardID into sg select new { StandardName =
stad.StandardName, Students = sg }; foreach (var group in studentsGroup)
{ Console.WriteLine(group.StandardName);
group.Students.ToList().ForEach(st =>
Console.WriteLine(st.StudentName)); }
Try it
Output:
Standard 1:
John
Steve
Standard 2:
Bill
Ram
Standard 3:

In the following example of group by query, we sort the group and select only
StudentName:

Example: LINQ Left Outer Join - C#


var studentsWithStandard = from stad in standardList join s in
studentList on stad.StandardID equals s.StandardID into sg from std_grp
in sg orderby stad.StandardName, std_grp.StudentName select new
{ StudentName = std_grp.StudentName, StandardName = stad.StandardName };
foreach (var group in studentsWithStandard) { Console.WriteLine("{0} is
in {1}", group.StudentName, group.StandardName); }
Try it
Output:
John is in Standard 1
Steve is in Standard 1
Bill is in Standard 2
Ram is in Standard 2

Sorting
The following query returns list of students by ascending order of StandardID
and Age.

Example: Sorting
var sortedStudents = from s in studentList orderby s.StandardID, s.age
select new { StudentName = s.StudentName, Age = s.age, StandardID =
s.StandardID }; sortedStudents.ToList().ForEach(s =>
Console.WriteLine("Student Name: {0}, Age: {1}, StandardID: {2}",
s.StudentName, s.Age , s.StandardID));
Try it
Output:
Student Name: Ron, Age: 21, StandardID: 0
Student Name: John, Age: 18, StandardID: 1
Student Name: Steve, Age: 21, StandardID: 1
Student Name: Bill, Age: 18, StandardID: 2
Student Name: Ram, Age: 20, StandardID: 2
Inner Join
Example: LINQ Inner join - C#
var studentWithStandard = from s in studentList join stad in
standardList on s.StandardID equals stad.StandardID select new
{ StudentName = s.StudentName, StandardName = stad.StandardName };
studentWithStandard.ToList().ForEach(s => Console.WriteLine("{0} is in
{1}", s.StudentName, s.StandardName ));
Try it
Output:
John is in Standard 1
Steve is in Standard 1
Bill is in Standard 2
Ram is in Standard 2

Nested Query
C#:
var nestedQueries = from s in studentList where s.age > 18 &&
s.StandardID == (from std in standardList where std.StandardName ==
"Standard 1" select std.StandardID).FirstOrDefault() select s;
nestedQueries.ToList().ForEach(s => Console.WriteLine(s.StudentName));
Try it
Output:
Steve

You might also like