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

Exercises: Building A Model Using Database First Workflow

The document describes building a video rental application called Vidzy using Entity Framework Core's database-first and code-first workflows. It outlines several iterations: 1) Initial model with videos and genres tables. 2) Changing to one-to-many relationship between videos and genres. 3) Adding video classification enum property. It then describes overriding conventions and adding tags functionality.

Uploaded by

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

Exercises: Building A Model Using Database First Workflow

The document describes building a video rental application called Vidzy using Entity Framework Core's database-first and code-first workflows. It outlines several iterations: 1) Initial model with videos and genres tables. 2) Changing to one-to-many relationship between videos and genres. 3) Adding video classification enum property. It then describes overriding conventions and adding tags functionality.

Uploaded by

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

Exercises By: Mosh Hamedani

Building a Model using Database First Workflow

Your job is to build an application for a video rental store called Vidzy. For the
purpose of this course, you don’t need to worry about user interface, so you’ll be
doing all these exercises in a console application.

1st Iteration
You attempt to build the Vidzy app in an iterative way. In the first iteration, you
want to implement the ability to add videos in the database.

You start by building your database first. So, create a new database called Vidzy.
Download the database script in the supplementary materials of this lecture and
run it on the Vidzy database to create the initial tables: Videos, Genres and
VideoGenres. (Note that here we are assuming there is a many-to-many
relationship between videos and genres.)

Once your database is ready, build an entity data model using database-first
workflow. Bring all the tables and spAddVideo stored procedure. We don’t prefix
method names with sp in C#. So, change the name of the function import to
AddVideo.

Use the AddVideo method to add a few videos to the database.

2nd Iteration
You realize that you over-engineered the solution and each Video needs one and
only one genre.

So, add a new NULLABLE tinyint column to Videos table called GenreId. Edit
the records in the table and assign them a genre.

Open the Videos table in the table designer again, remove the nullable attribute
from the GenreId column and create a relationship between Genres and Videos.

Next, drop the VideoGenres table.

1
Exercises By: Mosh Hamedani

Finally, modify the spAddVideo stored procedure accordingly so you can still add
new videos.

Bring the changes into your model. Note that there are two relationships between
Genre and Video: One many-to-many relationship (from before) and a new one-
to-many relationship because of the recent changes. So, as you see, sometimes
refreshing your model doesn’t quite work the way you expect. In this case, the old
relationship was not deleted, so you need to manually delete it.

Delete the many-to-many relationship and validate your model. Save the changes
and re-build the project. Ensure you can still add videos to the database in your
console application.

3rd Iteration
Vidzy tells you that they need to classify their videos into three categories: Silver,
Gold and Platinum. You decide to implement this by adding a new tinyint column
in the Videos table, called Classification. Make sure this column is not nullable
and use 1 as the default value to assign all existing videos to the silver category.

Modify the stored procedure accordingly.

Bring the changes into your model, and map the Classification property to a new
enum called: Classification. This enum should have three members: Silver, Gold
and Platinum.

Ensure you can still add new videos using your console application.

Solution
To see my solution, download the solution zip file. Temporarily rename your
database to Vidzy_Exercise. Create a new database called Vidzy and run the
SQL script included in the solution zip file on this database. This would be the

2
Exercises By: Mosh Hamedani

database after all changes in these iterations. Now you can open the console
application in Visual Studio and run the code.

3
Exercises By: Mosh Hamedani

Building a Model using Code First Workflow


Your job is to build an application for a video rental store called Vidzy. For the
purpose of this course, you don’t need to worry about user interface, so you’ll be
doing all these exercises in a console application.

1st Iteration
You attempt to build the Vidzy app in an iterative way. In the first iteration, you
want to implement the ability to add videos in the database.

Create a new console application and build the following model using the code-
first workflow:

Note that there is a many-to-many relationship between Video and Genre.

Use code-first migrations to generate the database and populate the Genres
table with some reference data.

Hint: Use two migrations, one for creating the tables, another for populating the
Genres table. (reason: if you include your INSERT INTO statements into the
InitialModel migration, and then you decide to overwrite it as a result of some
recent changes, you’ll lose all your INSERT INTO statements.)

Inspect the generated database and its tables.

1
Exercises By: Mosh Hamedani

2nd Iteration
You realize that you over-engineered the solution and each Video needs one and
only one genre.

Change your model such that each Video has only one Genre.

Use code-first migrations to update the database. Inspect the database and note
the changes to your tables.

3rd Iteration
Vidzy tells you that they need to classify their videos into three categories: Silver,
Gold and Platinum. You decide to implement this by using an enum:
Classification. Add a property of type Classification to your Video class.

Use code-first migrations to update the database. Inspect the database and note
the change to the Videos table.

Deployment
You’re ready to deploy the application. Your DBA expects you to provide a
database script. Run the following command to get a SQL script of all your
migrations:

Update-­‐Database  -­‐Script  -­‐SourceMigration:0  

This command generates the SQL script from the very first migration to the last
one. In a real-world scenario, you may want to change the range of migrations
included in the SQL script in each deployment. To do this, you can use:

Update-­‐Database  -­‐Script  -­‐SourceMigration:Migr1  -­‐TargetMigration:Migr2  

2
Exercises By: Mosh Hamedani

Overriding Code-First Conventions


These exercises are built on top of the exercises in the last section: Building a
Model using Code-First Workflow.

4th Iteration
In the last exercise, you generated a SQL script for your DBA to deploy the
database. He was not happy about the schema you provided and has requested
a few changes:

Videos table
• Name column cannot be NULL and its length should be maximum 255
characters.
• Genre_Id column should be renamed to GenreId, and it cannot be NULL.
• Classification column should be a tinyint.

Genres table
• Name column cannot be NULL and its length should be maximum 255
characters.

Implement the requested changes using Fluent API. Organize your configurations
into separates, one class per entity (see the lecture “Organizing Fluent API
Configurations” for more details).

Read the following hints before making any changes.

Hint 1: Open the Videos table and note the type of Classification column. The
reason this column is an int is because in C# enums are integers (by default). To
change the type of this column, you need to change the Classification enum as
follows:

public  enum  Classification  :  byte    

Hint 2: Once you override the default conventions and try to run Update-
Database, you’ll encounter the following error:

1
Exercises By: Mosh Hamedani

The object ‘DF__Videos__Classifi__1920BF5C’ is dependent on column


‘Classification’. ALTER TABLE ALTER COLUMN Classification failed because one
or more objects access this column.

In situations where you receive errors like this about database objects with some
random identifiers (eg DF__Videos__Classifi__1920BF5C), you need to inspect
your database in SQL Server Management Studio. Expand Videos >
Constraints and you’ll see the constraint. Right-click it and select Script
Constraint as > CREATE TO. This way you can see what this constraint does. In
this case, it sets 0 as the default value for Classification. This was automatically
added by one of your earlier code-first migrations.

The reason this constraint was added is because the Classification property of
Video class is not nullable. So, in situations like that, Entity Framework assigns
default values to prevent the migration from failing in case there are existing
records in the table.

So, to finish this exercise, you need to manually drop this unnecessary constraint.
Modify your current migration that includes schema changes and add the
following line at the beginning:

Sql(“ALTER  TABLE  dbo.Videos  DROP  CONSTRAINT  [constraint-­‐name]”);  

Be sure to replace [constraint-name] with the name of constraint in your


database.

Then run the migration to make the changes to the Videos table.

Hint 3: If you have a table open in the Table Designer in SQL Server
Management Studio and then update your database using code-first migrations,
you’ll not see the changes, even if you right-click on the table and open it again in
the designer. You need to close the existing table design session and re-open
your table in the designer.

Once you’ve made all the requested changes, generate a new script for your
DBA.

2
Exercises By: Mosh Hamedani

5th Iteration
Vidzy is happy with your job and want a new feature: the ability to tag videos.
Each video can have zero or more tags and each tag can be applied to zero or
more videos.

Change your model to satisfy this requirement. Unlike the last iteration where you
created a separate migration to overwrite code-first conventions, in this iteration,
override the default conventions at the same time as adding the new classes.

• The intermediary table for the many-to-many relationship between videos and
tags should be called VideoTags. 


• This table should have two columns: VideoId and TagId.

Apply the changes and create a new database script for your DBA.

3
Exercises By: Mosh Hamedani

Querying Data
Download Section 6 - Exercise Files.zip attached to this lecture and open the
solution in Visual Studio. This is the model for Vidzy video store built using the
code-first workflow. Whether you build a model using database-first or code-first
workflow, querying data is exactly the same. So you can use this solution to
exercise querying data.

Once you open the solution, go to Tools > Package Manager > Package
Manager Console and run Update-Database. This will generate a new database
called Vidzy_Queries populated with some data.

Write queries using LINQ extension methods to display:


• Action movies sorted by name




Output:


Die Hard

Terminator 2: Judgment Day

The Dark Knight

• Gold drama movies sorted by release date (newest first)




Output:


The Shawshank Redemption

Schindlre’s List



(Continued on the next page)

1
Exercises By: Mosh Hamedani

• All movies projected into an anonymous type with two properties:


MovieName and Genre


Output:


The Godfather

The Shawshank Redemption

Schindlre’s List

The Hangover

Anchorman

Die Hard

The Dark Knight

Terminator 2: Judgment Day

• All movies grouped by their classification: Project the group into a new
anonymous type with two properties: Classification (string), Movies
(IEnumerable<Video>). For each group, display the classification and list of
videos in that class sorted alphabetically. 


Output:


Classification: Silver

Anchorman


Classification: Gold

Die Hard

Schindlre’s List

The Dark Knight

The Hangover

The Shawshank Redemption


Classification: Platinum

Terminator 2: Judgment Day

The Godfather



Hint: after applying GroupBy, you need to use Select to do the projection.
Each group has a property called Key that you can use to get the

2
Exercises By: Mosh Hamedani

Classification. The group variable can be used to get all videos in that group.


• List of classifications sorted alphabetically and count of videos in them. 




Output:


Gold (5)

Platinum (2)

Silver (1)


• List of genres and number of videos they include, sorted by the number
of videos. Genres with the highest number of videos come first. 


Output:


Action (3)

Drama (3)

Comedy (2)

Horror (0)

Thriller (0)

Family (0)

Romance (0)

3
Exercises By: Mosh Hamedani

Loading Related Object


Download Section 7 - Exercise Files.zip attached to this lecture and open the
solution in Visual Studio. Then, go to Tools > Package Manager > Package
Manager Console and run Update-Database. This will generate a new database
called Vidzy_Queries populated with some data.

Write a query to load all videos in the database. Iterate over the videos and
display the name and genre of each video. You’ll get a NullReferenceException.
Why? Because you didn’t eager load the videos with their genres and lazy
loading is not working in the current solution.

Modify the code to enable lazy loading. Then run the program and ensure that
videos and their genres are displayed. Inspect the queries ran by Entity
Framework using SQL Profiler. Observe the N + 1 problem.

Next, use eager loading to solve the N + 1 problem. Inspect the queries using
SQL Profiler again and notice the difference.

As an alternative solution, use expect loading to solve the N + 1 problem.

1
Exercises By: Mosh Hamedani

Changing Data
Download Section 8 - Exercise Files.zip attached to this lecture and open the
solution in Visual Studio. Then, go to Tools > Package Manager > Package
Manager Console and run Update-Database. This will generate a new database
called Vidzy_UpdatingData populated with some data.

Note: For each exercise, create a separate method. Make sure that your
methods are properly named and they reflect the intent. Pay great attention to the
number and type of arguments for these methods so that they’re reusable. In the
Main() method, simply call each of your methods.

Note: In each method, wrap your context with the “using” block to ensure it’s
disposed at the end of the method. Example:

using  (var  context  =  new  Context())



{

}  

1- Add a new video called “Terminator 1” with genre Action, release date 26
Oct, 1984, and Silver classification. Ensure the Action genre is not duplicated in
the Genres table.

2- Add two tags “classics” and “drama” to the database. Ensure if your method
is called twice, these tags are not duplicated.

3- Add three tags “classics”, “drama” and “comedy” to the video with Id 1 (The
Godfather). Ensure the “classics” and “drama” tags are not duplicated in the
Tags table. Also, ensure that if your method is called twice, these tags are not
duplicated in VideoTags table.

4- Remove the “comedy” tag from the the video with Id 1 (The Godfather).

5- Remove the video with Id 1 (The Godfather).

6- Remove the genre with Id 2 (Action). Ensure all courses with this genre are
deleted from the database.

1
Data Annotations By: Mosh Hamedani

Tables
[Table(“tbl_Course”,  Schema  =  “catalog”  )]  
public  class  Course

{

}  

Columns
[Column(“sName”,  TypeName  =  “varchar”)]  
[Required]  
[MaxLength(255)]  
public  string  Name  {  get;  set;  }


Primary Keys
[Key]  
[DatabaseGenerated(DatabaseGeneratedOption.None)]  
public  class  Isbn  {  get;  set;  }


1
Data Annotations By: Mosh Hamedani

Composite Primary Keys


public  class  OrderItem  

{  
       [Key]  
       [Column(Order  =  1)]  
       public  int  OrderId  {  get;  set;  }


       [Key]  
       [Column(Order  =  2)]  
       public  int  OrderItemId  {  get;  set;  }


}  

Indices
[Index]  
public  int  AuthorId  {  get;  set;  }


[Index(IsUnique  =  true)]  
public  string  Name  {  get;  set;  }


2
Data Annotations By: Mosh Hamedani

Composite Indices
[Index(“IX_AuthorStudentsCount”,  1)]  
public  int  AuthorId  {  get;  set;  }


[Index(“IX_AuthorStudentsCount”,  2)]  
public  int  StudentsCount  {  get;  set;  }


Foreign Keys
public  class  Course  

{  
       [ForeignKey(“Author”)]  
       public  int  AuthorId  {  get;  set;  }


       public  Author  Author  {  get;  set;  }  


}  

3
Fluent API By: Mosh Hamedani

Basics
public  class  PlutoContext  :  DbContext

{  
       protected  override  void  OnModelCreating(DbModelBuilder  
modelBuilder)

       {

               modelBuilder

                           .Entity<Course>

                           .Property(t  =>  t.Name)

                           .IsRequired();  
       }

}  

Tables
Entity<Course>.ToTable(“tbl_Course”,  “catalog”);  

Primary Keys
Entity<Book>.HasKey(t  =>  t.Isbn);


Entity<Book>.Property(t  =>  t.Isbn)

     .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);


1
Fluent API By: Mosh Hamedani

Composite Primary Keys


Entity<OrderItem>.HasKey(t  =>  new  {  t.OrderId,  t.OrderId  });  

Columns
Entity<Course>.Property(t  =>  t.Name)

           .HasColumnName(“sName”)

           .HasColumnType(“varchar”)

           .HasColumnOrder(2)

           .IsRequired()

           .HasMaxLength(255);  

One-to-many Relationship
Entity<Author>

           .HasMany(a  =>  a.Courses)

           .WithRequired(c  =>  c.Author)

           .HasForeignKey(c  =>  c.AuthorId);  

Many-to-many Relationship
Entity<Course>

           .HasMany(c  =>  c.Tags)

           .WithMany(t  =>  t.Courses)

           .Map(m  =>  

             {

                 m.ToTable(“CourseTag”);  

                 m.MapLeftKey(“CourseId”);  

                 m.MapRightKey(“TagId”);

             });


2
Fluent API By: Mosh Hamedani

One-to-zero/one Relationship
Entity<Course>

           .HasOptional(c  =>  c.Caption)

           .WithRequired(c  =>  c.Course);


One-to-one Relationship
Entity<Course>

           .HasRequired(c  =>  c.Cover)

           .WithRequiredPrincipal(c  =>  c.Course);


Entity<Cover>

           .HasRequired(c  =>  c.Course)

           .WithRequiredDependent(c  =>  c.Cover);


3
LINQ Cheat Sheet By: Mosh Hamedani

Restriction
from  c  in  context.Courses  
where  c.Level  ==  1  
select  c;  

Ordering
from  c  in  context.Courses  
where  c.Level  ==  1  
orderby  c.Name,  c.Price  descending  
select  c;  

Projection
from  c  in  context.Courses  
select  new  {  Course  =  c.Name,  AuthorName  =  c.Author.Name  };  

Grouping
from  c  in  context.Courses  
group  c  by  c.Level  into  g  
select  g;  

from  c  in  context.Courses  


group  c  by  c.Level  into  g  
select  new  {  Level  =  g.Key,  Courses  =  g  };  

1
LINQ Cheat Sheet By: Mosh Hamedani

Inner Join
Use when there is no relationship between your entities and you need to link them based on a
key.

from  a  in  context.Authors  


join  c  in  context.Courses  on  a.Id  equals  c.AuthorId  
select  new  {  Course  =  c.Name,  Author  =  a.Name  };  

Group Join
Useful when you need to group objects by a property and count the number of objects in each
group. In SQL we do this with LEFT JOIN, COUNT(*) and GROUP BY. In LINQ, we use group
join.

from  a  in  context.Authors  


join  c  in  context.Courses  on  a.Id  equals  c.AuthorId  into  g  
select  new  {  Author  =  a.Name,  Courses  =  c.Count()  };  

Cross Join
To get full combinations of all objects on the left and the ones on the right.

from  a  in  context.Authors  


from  c  in  context.Courses  
select  new  {  Author  =  a.Name,  Course  =  c.Name  };


2
LINQ Cheat Sheet By: Mosh Hamedani

Restriction
context.Courses.Where(c  =>  c.Level  ==  1);  

Ordering
context.Courses  
             .OrderBy(c  =>  c.Name)    //  or  OrderByDescending  
             .ThenBy(c  =>  c.Level);  //  or  ThenByDescending  

Projection
context.Courses.Select(c  =>  new    
             {    
                       CourseName  =  c.Name,  
                       AuthorName  =  c.Author.Name    //  no  join  required  
             });  

//  flattens  hierarchical  lists  


var  tags  =  context.Courses.SelectMany(c  =>  c.Tags);  

Grouping
var  groups  =  context.Courses.GroupBy(c  =>  c.Level);  

1
LINQ Cheat Sheet By: Mosh Hamedani

Inner Join
Use when there is no relationship between your entities and you need to link them based on a
key.

var  authors  =  context.Authors.Join(context.Courses,  


         a  =>  a.Id,    //  key  on  the  left  side  
         c  =>  c.AuthorId,      //  key  on  the  right  side,  
         (author,  course)  =>      //  what  to  do  once  matched

               new  

               {

                       AuthorName  =  author.Name,

                       CourseName  =  course.Name

               }

);  

Group Join
Useful when you need to group objects by a property and count the number of objects in each
group. In SQL we do this with LEFT JOIN, COUNT(*) and GROUP BY. In LINQ, we use group
join.

var  authors  =  context.Authors.GroupJoin(context.Courses,  


         a  =>  a.Id,    //  key  on  the  left  side  
         c  =>  c.AuthorId,      //  key  on  the  right  side,  
         (author,  courses)  =>      //  what  to  do  once  matched

               new  

               {

                       AuthorName  =  author.Name,

                       Courses  =  courses

               }

);  

2
LINQ Cheat Sheet By: Mosh Hamedani

Cross Join
To get full combinations of all objects on the left and the ones on the right.

var  combos  =  context.Authors.SelectMany(a  =>  context.Courses,  



       (author,  course)  =>  new  {

               AuthorName  =  author.Name,

               CourseName  =  course.Name  

       });  
               

Partitioning
To get records in a given page.

context.Courses.Skip(10).Take(10);  

Element Operators
//  throws  an  exception  if  no  elements  found    
context.Courses.First();  
context.Courses.First(c  =>  c.Level  ==  1);  

//  returns  null  if  no  elements  found    


context.Courses.FirstOrDefault();    

//  not  supported  by  SQL  Server  


context.Courses.Last();  
context.Courses.LastOrDefault();  

context.Courses.Single(c  =>  c.Id  ==  1);  


context.Courses.SingleOrDefault(c  =>  c.Id  ==  1);  

3
LINQ Cheat Sheet By: Mosh Hamedani

Quantifying
bool  allInLevel1  =  context.Courses.All(c  =>  c.Level  ==  1);  

bool  anyInLevel1  =  context.Courses.Any(c  =>  c.Level  ==  1);  

Aggregating
int  count  =  context.Courses.Count();  
int  count  =  context.Courses.Count(c  =>  c.Level  ==  1);  

var  max  =  context.Courses.Max(c  =>  c.Price);  


var  min  =  context.Courses.Min(c  =>  c.Price);  
var  avg  =  context.Courses.Average(c  =>  c.Price);  
var  sum  =  context.Courses.Sum(c  =>  c.Price);  

4
LINQ Cheat Sheet By: Mosh Hamedani

Restriction
context.Courses.Where(c  =>  c.Level  ==  1);  

Ordering
context.Courses  
             .OrderBy(c  =>  c.Name)    //  or  OrderByDescending  
             .ThenBy(c  =>  c.Level);  //  or  ThenByDescending  

Projection
context.Courses.Select(c  =>  new    
             {    
                       CourseName  =  c.Name,  
                       AuthorName  =  c.Author.Name    //  no  join  required  
             });  

//  flattens  hierarchical  lists  


var  tags  =  context.Courses.SelectMany(c  =>  c.Tags);  

Grouping
var  groups  =  context.Courses.GroupBy(c  =>  c.Level);  

1
LINQ Cheat Sheet By: Mosh Hamedani

Inner Join
Use when there is no relationship between your entities and you need to link them based on a
key.

var  authors  =  context.Authors.Join(context.Courses,  


         a  =>  a.Id,    //  key  on  the  left  side  
         c  =>  c.AuthorId,      //  key  on  the  right  side,  
         (author,  course)  =>      //  what  to  do  once  matched

               new  

               {

                       AuthorName  =  author.Name,

                       CourseName  =  course.Name

               }

);  

Group Join
Useful when you need to group objects by a property and count the number of objects in each
group. In SQL we do this with LEFT JOIN, COUNT(*) and GROUP BY. In LINQ, we use group
join.

var  authors  =  context.Authors.GroupJoin(context.Courses,  


         a  =>  a.Id,    //  key  on  the  left  side  
         c  =>  c.AuthorId,      //  key  on  the  right  side,  
         (author,  courses)  =>      //  what  to  do  once  matched

               new  

               {

                       AuthorName  =  author.Name,

                       Courses  =  courses

               }

);  

2
LINQ Cheat Sheet By: Mosh Hamedani

Cross Join
To get full combinations of all objects on the left and the ones on the right.

var  combos  =  context.Authors.SelectMany(a  =>  context.Courses,  



       (author,  course)  =>  new  {

               AuthorName  =  author.Name,

               CourseName  =  course.Name  

       });  
               

Partitioning
To get records in a given page.

context.Courses.Skip(10).Take(10);  

Element Operators
//  throws  an  exception  if  no  elements  found    
context.Courses.First();  
context.Courses.First(c  =>  c.Level  ==  1);  

//  returns  null  if  no  elements  found    


context.Courses.FirstOrDefault();    

//  not  supported  by  SQL  Server  


context.Courses.Last();  
context.Courses.LastOrDefault();  

context.Courses.Single(c  =>  c.Id  ==  1);  


context.Courses.SingleOrDefault(c  =>  c.Id  ==  1);  

3
LINQ Cheat Sheet By: Mosh Hamedani

Quantifying
bool  allInLevel1  =  context.Courses.All(c  =>  c.Level  ==  1);  

bool  anyInLevel1  =  context.Courses.Any(c  =>  c.Level  ==  1);  

Aggregating
int  count  =  context.Courses.Count();  
int  count  =  context.Courses.Count(c  =>  c.Level  ==  1);  

var  max  =  context.Courses.Max(c  =>  c.Price);  


var  min  =  context.Courses.Min(c  =>  c.Price);  
var  avg  =  context.Courses.Average(c  =>  c.Price);  
var  sum  =  context.Courses.Sum(c  =>  c.Price);  

4
LINQ Cheat Sheet By: Mosh Hamedani

Restriction
from  c  in  context.Courses  
where  c.Level  ==  1  
select  c;  

Ordering
from  c  in  context.Courses  
where  c.Level  ==  1  
orderby  c.Name,  c.Price  descending  
select  c;  

Projection
from  c  in  context.Courses  
select  new  {  Course  =  c.Name,  AuthorName  =  c.Author.Name  };  

Grouping
from  c  in  context.Courses  
group  c  by  c.Level  into  g  
select  g;  

from  c  in  context.Courses  


group  c  by  c.Level  into  g  
select  new  {  Level  =  g.Key,  Courses  =  g  };  

1
LINQ Cheat Sheet By: Mosh Hamedani

Inner Join
Use when there is no relationship between your entities and you need to link them based on a
key.

from  a  in  context.Authors  


join  c  in  context.Courses  on  a.Id  equals  c.AuthorId  
select  new  {  Course  =  c.Name,  Author  =  a.Name  };  

Group Join
Useful when you need to group objects by a property and count the number of objects in each
group. In SQL we do this with LEFT JOIN, COUNT(*) and GROUP BY. In LINQ, we use group
join.

from  a  in  context.Authors  


join  c  in  context.Courses  on  a.Id  equals  c.AuthorId  into  g  
select  new  {  Author  =  a.Name,  Courses  =  c.Count()  };  

Cross Join
To get full combinations of all objects on the left and the ones on the right.

from  a  in  context.Authors  


from  c  in  context.Courses  
select  new  {  Author  =  a.Name,  Course  =  c.Name  };


2
LINQ Cheat Sheet By: Mosh Hamedani

Restriction
context.Courses.Where(c  =>  c.Level  ==  1);  

Ordering
context.Courses  
             .OrderBy(c  =>  c.Name)    //  or  OrderByDescending  
             .ThenBy(c  =>  c.Level);  //  or  ThenByDescending  

Projection
context.Courses.Select(c  =>  new    
             {    
                       CourseName  =  c.Name,  
                       AuthorName  =  c.Author.Name    //  no  join  required  
             });  

//  flattens  hierarchical  lists  


var  tags  =  context.Courses.SelectMany(c  =>  c.Tags);  

Grouping
var  groups  =  context.Courses.GroupBy(c  =>  c.Level);  

1
LINQ Cheat Sheet By: Mosh Hamedani

Inner Join
Use when there is no relationship between your entities and you need to link them based on a
key.

var  authors  =  context.Authors.Join(context.Courses,  


         a  =>  a.Id,    //  key  on  the  left  side  
         c  =>  c.AuthorId,      //  key  on  the  right  side,  
         (author,  course)  =>      //  what  to  do  once  matched

               new  

               {

                       AuthorName  =  author.Name,

                       CourseName  =  course.Name

               }

);  

Group Join
Useful when you need to group objects by a property and count the number of objects in each
group. In SQL we do this with LEFT JOIN, COUNT(*) and GROUP BY. In LINQ, we use group
join.

var  authors  =  context.Authors.GroupJoin(context.Courses,  


         a  =>  a.Id,    //  key  on  the  left  side  
         c  =>  c.AuthorId,      //  key  on  the  right  side,  
         (author,  courses)  =>      //  what  to  do  once  matched

               new  

               {

                       AuthorName  =  author.Name,

                       Courses  =  courses

               }

);  

2
LINQ Cheat Sheet By: Mosh Hamedani

Cross Join
To get full combinations of all objects on the left and the ones on the right.

var  combos  =  context.Authors.SelectMany(a  =>  context.Courses,  



       (author,  course)  =>  new  {

               AuthorName  =  author.Name,

               CourseName  =  course.Name  

       });  
               

Partitioning
To get records in a given page.

context.Courses.Skip(10).Take(10);  

Element Operators
//  throws  an  exception  if  no  elements  found    
context.Courses.First();  
context.Courses.First(c  =>  c.Level  ==  1);  

//  returns  null  if  no  elements  found    


context.Courses.FirstOrDefault();    

//  not  supported  by  SQL  Server  


context.Courses.Last();  
context.Courses.LastOrDefault();  

context.Courses.Single(c  =>  c.Id  ==  1);  


context.Courses.SingleOrDefault(c  =>  c.Id  ==  1);  

3
LINQ Cheat Sheet By: Mosh Hamedani

Quantifying
bool  allInLevel1  =  context.Courses.All(c  =>  c.Level  ==  1);  

bool  anyInLevel1  =  context.Courses.Any(c  =>  c.Level  ==  1);  

Aggregating
int  count  =  context.Courses.Count();  
int  count  =  context.Courses.Count(c  =>  c.Level  ==  1);  

var  max  =  context.Courses.Max(c  =>  c.Price);  


var  min  =  context.Courses.Min(c  =>  c.Price);  
var  avg  =  context.Courses.Average(c  =>  c.Price);  
var  sum  =  context.Courses.Sum(c  =>  c.Price);  

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy