LINQ makes working with data a real joy. It
automatically handles relationships, hierarchy, and tracking changes within our
model – eliminating tons of data access code.
For example, to create a new album and a photo within it, I
could extend our previous code-sample like this:
Listing 3
PhotoDB photoDb = new PhotoDB();
Photographer photographer1 = new Photographer();
photographer1.PhotographerName = "Scott Guthrie";
Photo photo1 = new Photo();
photo1.Description = "Picture of Lion";
photo1.Url = "http://someurl";
photo1.Thumbnail = "http://thumbnailurl";
photo1.Photographer = photographer1;
Album album1 = new Album();
album1.AlbumName = "Africa Trip";
album1.Photos.Add(photo1);
photoDb.Albums.Add(album1);
photoDb.SubmitChanges();
This is all of the code needed to add a new Photographer,
Photo and Album into the database, setup the FK relationship between the
Photographer and Photo, and setup the Photo and the Album FK relationship
(notice how this relationship is expressed by adding the photo into the Album’s
photo collection, and by setting the Photographer property on Photo).
Because these properties and collections are strongly-typed, we get full
compile-time checking and intellisense of our syntax and data relationships.
C# has also added new syntax support that can be used to
make object initialization even terser/cleaner than what I did above.
Specifically, it now allows developers to declare properties (and collections)
using syntax like below if you prefer:
Listing 4
PhotoDB photoDb = new PhotoDB();
Photographer scott = new Photographer()
{
PhotographerName = "Scott Guthrie"
};
photoDb.Albums.Add(new Album()
{
AlbumName = "South Africa", Photos =
{
new Photo()
{
Description = "Lion Close Up", Photographer = scott, Url = "http://url1",
Thumbnail = "http://thumb1",
}
, new Photo()
{
Description = "Zebras at Dusk", Photographer = scott, Url =
" http://url2", Thumbnail = " http://thumb2",
}
}
}
);
photoDb.SubmitChanges();
This is syntactically equivalent to the code before – except
that we are now able to compact more functionality in fewer lines of
code. In the example above, I’m now adding two new photos to the new South Africa album (with me as the photographer for both pictures).
Because we setup FK relationships between the Photo table
and the Tags table, we get automatic association linking between them with LINQ
(this is expressed via the “Tags” property on Photos and the corresponding
“Photo” property on each Tag). For example, I could use the below code to
fetch one of our newly created Photo’s above from the database and associate
three new Tags to it:
Listing 5
PhotoDB photoDB = new PhotoDB();
Photo photo = photoDB.Photos.Single(p = > p.Description == "Lion Close Up");
photo.Tags.Add(new Tag()
{
Name = "Lion"
}
);
photo.Tags.Add(new Tag()
{
Name = "AndersH"
}
);
photo.Tags.Add(new Tag()
{
Name = "ScottGu"
}
);
photoDb.SubmitChanges();
I could then use the below code to retrieve a Photo and
output its tags within a page:
PhotoDB photoDB = new PhotoDB();
Photo photo = photoDB.Photos.Single(p = > p.Description == "Lion Close Up");
foreach (Tag tag in photo.Tags)
{
Response.Write("Tag : " + tag.Name);
}
I could also then write this code to easily retrieve all
Photos that are tagged with a specific tag-name, and output the Photo
description and photographer name for each of them:
Listing 6
PhotoDB photoDb = new PhotoDB();
string tagName = "Lion";
var photos = from photo in photoDb.Photos where photo.Tags.Any(t = > t.Name ==
tagName)select photo;
foreach (Photo photo in photos)
{
Response.Write("Photo: " + photo.Description + " by: " +
photo.Photographer.PhotographerName);
}
I do not need to write any extra data code to make the above
code work. LINQ handles all of the SQL statement execution for me.
This provides an incredibly flexible and elegant way to perform data access.