BTI420 notes – Tue Jan 20

View model classes. Collections. Data relations/associations. LINQ (language-integrated query). Get data from a user.

Busy day today. Lots of topics. Lots of code examples in the GitHub repository’s “Week_02″ folder.

.

Quiz 1 is today

Quiz 1 is today. We will probably do it at the end of the timeslot, beginning at 9:30am.

The quiz will be ten (10) minutes in length.

You will answer two or three questions, on a single sheet of paper. The questions will cover topics, concepts, definitions, descriptions, and so on. Think about a question-and-answer session in a job interview. Those are the kinds of questions you can expect.

.

Code examples for today

1. Collections

2. RelatedData

3. IntroToLINQ

.

Object initializers

You have learned how to create and configure a new object. Something like this:

var peter = new Person();
peter.FirstName = “Peter”;
peter.LastName = “McIntyre”;
peter.Age = 29;
// etc.

Well, you can also use a nifty C# language feature, called object initializers. Here’s an example:

var peter = new Person { FirstName = “Peter”, LastName = “McIntyre”, Age = 29 };

If your task is short enough, do it on one line. Otherwise, you can use multiple lines of code.

You’re welcome.

.

The role of a view model class

We need to talk about view model classes. This is an important topic.

Yes, this is an important topic.

It is the topic that is NOT covered in the textbook.

Therefore, you must adapt the use of the textbook’s coverage and code examples to our course delivery, because you MUST use view models.

.

A view model class takes on the exact shape of the data you wish to work with in a view (as defined in the model-view-controller architecture).

A view model class can define the data that is delivered to a user.

Or, it can define the data that is gathered from a user.

.

What are view model classes? Why have them?

As noted above, a view model class takes on the exact shape of the data you wish to work with in a view.

The properties in a view model class are based on the properties in a design model class.

Our goal is to prevent design model classes from being visible and accessible in controllers and views. Instead, in controllers and views, we will use view model classes. This implies that we must map data between design model classes, and view model classes.

This will help to implement the “separation of concerns” principle.

.

How to create view model classes

View model classes, for this BTI420 course, should be written in the Controllers folder.

We suggest that you create a separate source code file to hold the view model classes needed for each controller. For example, assume that you have a “Suppliers and Products” domain model. Therefore, you should create a source code file named “Supplier_vm.cs”, and another named “Product_vm.cs”.

What classes do you write? The answer is totally and completely dependent upon your app’s use cases. However, there are some common and obvious use case patterns.

.

Collections

It’s time to learn about collections.

When we work with data in our web apps, we are going to do lots of work with objects, and collections of objects.

The following is from the MSDN Library Collections and Data Structures document:

Closely related data can be handled more efficiently when grouped together into a collection. Instead of writing separate code to handle each individual object, you can use the same code to process all the elements of a collection.

To manage a collection, you can … add, remove, and modify either individual elements or a range of elements in the collection.

Here’s some more information, from the MSDN Library:

Commonly Used Collection Types (we will use ICollection<T>, List<T>, and IEnumerable<T>)

When To Use Generic Collections

Introduction to Generics (first paragraph only)

List<T> Class reference

A collection can be created and used anywhere in your code. We also see collections as properties in data classes. When we declare a collection property in a data class, we often use the data type ICollection<T>. The T is a type name placeholder, which will be replaced by the actual collection type (e.g. Person, Vehicle, Product, etc.).

Reference information is described in the ICollection<T> document. (To search for this yourself, use this search engine term: msdn library icollection<t> interface) The “Remarks” and “Examples” sections of that document will help you learn.

When you add a property of type ICollection<T>, you MUST do one other task: In the default constructor, initialize the property by using a concrete type.

ICollection<T> is an interface. You can tell, because .NET Framework interfaces have an upper-case letter “I” prefix. In C++ programming, you learned about an abstract class with pure virtual methods. In C# and the .NET Framework, the counterpart is an interface.

best practice tells us to use an interface as the data type when declaring properties in a class. However, just as in C++, we cannot initialize an interface. Instead, we must use a concrete type that implements/inherits the interface. (Why don’t we just declare the property’s data type as the concrete type? Well, it’s not a best practice. You’ll understand more later.)

So, in a data class that has a collection property (probably named “Products”, of data type “Product”), we write the following code in the default constructor:

this.Products = new List<Product>();

.

Data relations/associations

We will discuss, study, and code some typical relations, or associations, between entities. Examples we’ll use:

  • Supplier – Product
  • (from the School of ICT…) academic Program – Subject
  • vehicle Manufacturer – Vehicle

.

Kinds of associations

Real-life and software objects can have associations between them. When writing data classes, the associations are simply coded as properties. However, they’re often called “navigation properties“.

There are several kinds of associations that you could code:

  • one to many (this is the one we’ll study first, because it’s simple and easy to understand)
  • many to many
  • one to one
  • to one, self-associated
  • to many, self-associated

.

Declaring a navigation property

When writing associated classes, ALWAYS add a navigation property to both associated classes.

Declare a to-one property with the data type of the associated class. For example if a Product is sold by a single Supplier:
public Supplier Supplier { get; set; }

Declare a to-many property with a collection type of the associated class. For example, a Supplier sells a number of Product items:
public ICollection<Product> Products { get; set; }

(Remember, whenever you declare a collection property, you MUST initialize it in a default constructor.)

.

Setting the value of a navigation property

Before setting the value of a navigation property, you must have a reference to an object (of that data type). Although you can create a new object in the statement, you will often have another existing variable for (or reference to) the object.

Set a to-one property as follows. Assume that ‘walmart’ is a Supplier object, and ‘shirt’ is a Product object:
shirt.Supplier = walmart;

Setting a to-many property requires some thought. Do you want to add a new object to the collection? Do you want to replace the existing collection with a new collection? Here are some examples, using the same ‘walmart’ and ‘shirt’ objects, but we also have a collection of toaster objects named ‘toasters’:
walmart.Products.Add(shirt); // add a new object to the collection
walmart.Products = toasters; // replace the existing collection with a new collection

Important: When you write a statement in code to set one end of the association, do you need to write another statement to set the other end? It depends:

  • During the first few weeks, when we use in-memory objects, YES, we must set both ends of the association.
  • Later in the course, when we use a persistent store (SQL Server via the Entity Framework), NO, we don’t have to. In this scenario, when you set one end of the association, the persistence framework sets both ends of the association.

.

Getting the value of a navigation property

Getting the value of a navigation property is natural and simple. Just pay attention to data types (an object, or a collection of objects).

Also, when you have a to-one association, it’s easy to ‘walk’ the object graph to get access to properties in the associated object. For example, using the ‘shirt’ object from above, you could get the “Name” or “Address” of the supplier:
string supplierName = shirt.Supplier.Name;

.

LINQ (language-integrated query)

LINQ – language-integrated query – is a C# language feature that supports in-language operations on data.

The operations include the full range of query, add, change, and remove. The data store can include a wide range of possibilities, from in-memory object collections, the file system, a relational database, and a remote/web service/cloud store.

When you use LINQ, you can use either one of two syntax forms:

  • query expression
  • fluent

.

“Query expression” syntax

For those familiar with relational database querying, the LINQ query expression syntax will appear familiar. A typical query expression consists of these parts:

from …
where …
orderby …
select …

So, a typical query expression looks like this:

linq_query_expression

.

In the “from” clause, “m” is known as a local range variable, which represents the items in the data source during the query. A local range variable can be one character, or it can be two or more characters.

.

“Fluent” syntax

Fluent syntax uses methods, and method chains, to do the work. The example from above would look like this:

linq_fluent

.

For readability, we can also use multiple lines, if you split before the dot:

linq_fluent_split

.

Note that many of the methods require a code expression; a function. The function could extract, filter, or project – the developer decides its behaviour.

The function syntax is known as a lambda expression in C#. (It is often referred to as an inline method. More generically, it is known as an anonymous function.) The syntax below shows a lambda expression that returns an entity object that matches a specific condition:

c => c.CustomerID == 23

The return type is inferred from the context in which it is used. In other words, if the lambda expression is used as an argument to a LINQ statement that is supposed to return an entity object, then the return type of the lambda expression above is the entity object type.

Anonymous functions can “see” the local variables in the surrounding methods. Repeating the example syntax above, assume that the method that surrounds the lambda expression includes a local variable named “custID”, and the variable held the value “23”. The new syntax would be:

c => c.CustomerID == custID

Note that if there is already a local variable named “c” in the surrounding methods, you must use a different local range variable.

How do you read or pronounce this syntax? As suggested by Hejlsberg and others (see this StackOverflow article), it can be read as any one of the following:

such that c.CustomerID is equal to custID

becomes (the result of) c.CustomerID equals custID

for which c.CustomerID is equal to custID

maps to c.CustomerID equals custID

lambda of c.CustomerID is equal to custID

.

For more examples, study the “Getting started…” section of the LINQ article by Hejlsberg and Box (linked below).

To get started learning about LINQ, study this document: LINQ: .NET Language Integrated Query, by Anders Hejlsberg and Don Box

Be sure to read at least these sections:

  • .NET Language-Integrated Query
  • Getting Started with Standard Query Operators
  • Lambda Expressions and Expression Trees

.

Get data from a user, brief introduction

There are many ways to get data from a user into your app. Today, we will study three ways:

  1. From the URI, as query string data
  2. From an HTML Form, by reading the values in the request body data
  3. From an HTML Form, by using the preferred way, which is to use a strongly-typed view model

.

More coverage will happen during the next class/session.

.

.

.

.

.

.

.

.

.

.

.

.

.

.

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: