Wednesday, January 29, 2014

DbGeography code first


EF5 Onwards Only - The features, APIs, etc. discussed in this page were introduced in Entity Framework 5. If you are using an earlier version, some or all of the information does not apply.


The video and step-by-step walkthrough shows how to map spatial types with Entity Framework Code First. It also demonstrates how to use a LINQ query to find a distance between two locations.
This walkthrough will use Code First to create a new database, but you can also use Code First to map to an existing database.
Spatial type support was introduced in Entity Framework 5. Note that to use the new features like spatial type, enums, and Table-valued functions, you must target .NET Framework 4.5. Visual Studio 2012 targets .NET 4.5 by default.
To use spatial data types you must also use an Entity Framework provider that has spatial support. See provider support for spatial types for more information.
There are two main spatial data types: geography and geometry. The geography data type stores ellipsoidal data (for example, GPS latitude and longitude coordinates). The geometry data type represents Euclidean (flat) coordinate system.

Pre-Requisites

You will need to have Visual Studio 2012, Ultimate, Premium, Professional, or Web Express edition installed to complete this walkthrough.

Set up the Project

  1. Open Visual Studio 2012
  2. On the File menu, point to New, and then click Project
  3. In the left pane, click Visual C#, and then select the Console template
  4. Enter SpatialCodeFirst as the name of the project and click OK

Define a New Model using Code First

When using Code First development you usually begin by writing .NET Framework classes that define your conceptual (domain) model. The code below defines the University class.
The University has the Location property of the DbGeography type. To use the DbGeography type, you must add a reference to the System.Data.Entity assembly and also add the System.Data.Spatial using statement.
Open the Program.cs file and paste the following using statements at the top of the file:
using System.Data.Spatial;
Add the following University class definition to the Program.cs file.
public class University  
{ 
    public int UniversityID { get; set; } 
    public string Name { get; set; } 
    public DbGeography Location { get; set; } 
}

Define the DbContext Derived Type

In addition to defining entities, you need to define a class that derives from DbContext and exposes DbSet<TEntity> properties. The DbSet<TEntity> properties let the context know which types you want to include in the model.
An instance of the DbContext derived type manages the entity objects during run time, which includes populating objects with data from a database, change tracking, and persisting data to the database.
The DbContext and DbSet types are defined in the EntityFramework assembly. We will add a reference to this DLL by using the EntityFramework NuGet package.
  1. In Solution Explorer, right-click on the project name.
  2. Select Manage NuGet Packages…
  3. In the Manage NuGet Packages dialog, Select the Online tab and choose the EntityFramework package.
  4. Click Install
Note, that in addition to the EntityFramework  assembly, a reference to the System.ComponentModel.DataAnnotations assembly is also added.
At the top of the Program.cs file, add the following using statement:
using System.Data.Entity;
In the Program.cs add the context definition. 
public partial class UniversityContext : DbContext 
{ 
    public DbSet<University> Universities { get; set; } 
}

Persist and Retrieve Data

Open the Program.cs file where the Main method is defined. Add the following code into the Main function.
The code adds two new University objects to the context. Spatial properties are initialized by using the DbGeography.FromText method. The geography point represented as WellKnownText is passed to the method. The code then saves the data. Then, the LINQ query that that returns a University object where its location is closest to the specified location, is constructed and executed.
using (var context = new UniversityContext ()) 
{ 
    context.Universities.Add(new University() 
        { 
            Name = "Graphic Design Institute", 
            Location = DbGeography.FromText("POINT(-122.336106 47.605049)"), 
        }); 
 
    context. Universities.Add(new University() 
        { 
            Name = "School of Fine Art", 
            Location = DbGeography.FromText("POINT(-122.335197 47.646711)"), 
        }); 
 
    context.SaveChanges(); 
 
    var myLocation = DbGeography.FromText("POINT(-122.296623 47.640405)"); 
 
    var university = (from u in context.Universities 
                        orderby u.Location.Distance(myLocation) 
                        select u).FirstOrDefault(); 
 
    Console.WriteLine( 
        "The closest University to you is: {0}.", 
        university.Name); 
}
Compile and run the application. The program produces the following output:
The closest University to you is: School of Fine Art.

View the Generated Database

When you run the application the first time, the Entity Framework creates a database for you. Because we have Visual Studio 2012 installed, the database will be created on the LocalDB instance. By default, the Entity Framework names the database after the fully qualified name of the derived context (in this example that is SpatialCodeFirst.UniversityContext). The subsequent times the existing database will be used.  
Note, that if you make any changes to your model after the database has been created, you should use Code First Migrations to update the database schema. See Code First to a New Database for an example of using Migrations.
To view the database and data, do the following:
  1. In the Visual Studio 2012 main menu, select View -> SQL Server Object Explorer.
  2. If (localdb)\v11.0 is not in the list of servers, click the right mouse button on SQL Server and select Add SQL Server
    Use the default Windows Authentication to connect to the (localdb)\v11.0 server
  3. Expand (localdb)\v11.0
  4. Unfold the Databases folder to see the new database and browse to the Universities table
  5. To view data, right-click on the table and select View Data

Summary

In this walkthrough we looked at how to use spatial types with Entity Framework Code First. 

Thursday, January 23, 2014

HttpContext.Items - a Per-Request Cache Store

Published: Wednesday, June 9, 2004

HttpContext.Items - a Per-Request Cache Store

By Scott Mitchell



Introduction


Each time a Web server receives a request for an ASP.NET resource - be it an ASP.NET Web page, a Web service, or any other request that is mapped in IIS to the ASP.NET engine - an instance of the System.Web.HttpContext object is created. This class contains information about the request. For example, the HttpContext class has the "intrinsic" objects you're familiar with: RequestResponseSessionApplicationServer, and CacheHttpContext contains information about the current user making the request in its User property, it stores information about any errors that have occurred in its Errors property.

One property of the HttpContext object that not many ASP.NET developers know about is the Items property, which is a Hashtable for storing and retrieving information on a per-request basis. That is, the various objects that participate in an ASP.NET request - the ASP.NET Web page, User Controls, custom compiled controls, HTTP modules, and class libraries used during the page request - all have access to the HttpContext object and therefore can all read from and write to the Items Hashtable. This Hashtable, then, proves useful as a centralized data store that lasts only the length of the request that all participants involved in the request can access.
The Items Hashtable can be employed as a per-request cache store, acting as a repository for data that is shared among disparate actors in the ASP.NET request life cycle. This article was inspired by Rob Howard's TechEd 2004 presentation BlackBelt ASP.NET, whose slides and code can be downloaded from this blog entry; during Rob's talk I kept an outline of the presentation, which is available on my blog.

Scenarios Where HttpContext.Items Caching Makes Sense


While all of the logic and user interface elements for an ASP.NET Web page can be placed entirely within the ASP.NET Web page and code-behind class itself, many developers wisely use User Controls, custom compiled controls, and custom class libraries to create a solidapplication architecture that's easy to understand, maintain, and update. While this approach is ideal, it can be a bit frustrating if, after componentizing your pages, you find that each individual unit needs to work with similar data.For example, imagine you were building an eCommerce Web site. On each page there may be various User Controls or compiled custom controls that displayed information about the current product, reviews of the product, the logged-in user's information, and so forth. A myriad of these controls might need to access similar bits of information from the database. The page might have one User Control that displays information about the current product, with another User Control displaying information about the product's manufacturer. Since this information is abstracted into two separate User Controls, each User Control must hit the database to retrieve the pertinent information. However, since the product and its manufacturer are related, this information could be easily brought back with one query using aJOIN statement.
There are even cases where database access is quite needlessly replicated. Perhaps at the top of the page there's a User Control that displays a brief summary of the user's shopping cart. This control might be repeated at the bottom. Both instances of the controls would need to access the database, thereby taking two queries instead of one.
In all of these examples, there's a common thread - by dividing the page into pieces the separate pieces are unable to easily share their repeated or similar bits of information, information that may require an expensive database access. Ideally, these separate page building blocks would be capable of sharing this information. Well, they can, by using the HttpContext class's Items Hashtable.

Examining the HttpContext class's Items Hashtable


In order to improve performance, it makes that we'd want to cache the shared bits of information among the various pieces of an ASP.NET Web page. But where should this information be cached? One option would be to use ASP.NET's data cache - after all, we have access to this Cache via the HttpContext object. This data cache is a good choice if you are working with data that is fairly static and is common across all users and all pages. But the data you may be working with might be unique to each user, or might be changing often.
For More on the ASP.NET Data Cache...
For more information on ASP.NET's data cache, be sure to check out Scott McFarland's article Caching with ASP.NET, which examines all of ASP.NET's caching techniques - output caching, fragment caching, and data caching.
For such situations, we can cache the data on a per-request basis. That is, if we have two User Controls on the page that need the same database data, rather than having them both hit the database, whoever hits the database first can cache the data for that request. The second User Control, then, can simply reference this cached data. The HttpContext class's Items collection provides a repository for stashing objects on a per-request basis.
To accomplish this, the User Controls and custom compiled controls need to access their data by first checking in the HttpContext.Items Hashtable. If the data is found there, then great, time saved calling the database. If not, the User Control or compiled control needs to get the data from the database and then add it to the Hashtable. Imagine that you had a set of custom business objects, one class being a UserInfo class, which contains properties pertinent to a user for your site. Furthermore, assume that there's a data access layer class, DAL, with a static method called GetUserByUserId(int), which takes in an integer user ID and returns a UserInfo object populated with the particular user's information. You could put the code to store the returned UserInfo instance in the HttpContext.Items Hashtable directly in each User Control and compiled control, like so:
... inside the User Control ...

... We need to get information about User X ...

// C#
int X = 4;

// See if User X is in the Items Hashtable
UserInfo u = (UserInfo) HttpContext.Current.Items["user" + X.ToString()];
if (u == null)
{
  // get the user and add it to the Items Hashtable
  u = DAL.GetUserByUserId(X);
  HttpContext.Current.Items["user" + X.ToString()] = u;
}


' VB.NET...
Dim X as Integer = 4

'See if User X is in the Items Hashtable
Dim u as UserInfo = CType(HttpContext.Current.Items("user" & X), UserInfo)
If u Is Nothing Then
  ' get the user and add it to the Items Hashtable
  u = DAL.GetUserById(X)
  HttpContext.Current.Items("user" & X) = u
End If
Now, imagine that you have two User Controls on the page, both using the above code to access information about users. Assume the first User Control is rendered first, and it gets information about user X. Since the Items Hashtable's lifetime is just for the request, it will not have any cached user information in it, so the User Control will add a new UserInfo object into the Hashtable with the key userX. No benefit gained here. But when the second User Control gets information about user X, it can bypass the call down to the data access layer, since that information is cached in the Items Hashtable. The performance benefits are multiplied on pages with numerous User Controls and custom compiled controls that use similar bits of data.
Want to Learn More About Hashtables?
The HttpContext.Items is a Hashtable. A Hashtable is an associative array, one whose elements are indexed by a key value rather than by an ordinal index. Hashtables are interesting data structures, as they offer constant-time searches, when searching by the key. To learn more about Hashtables, and how they can offer such great performance, be sure to read: An Extensive Examination of Data Structures: Part 2.

A Better Approach - Moving the HttpContext.Items Check Out of the User Controls and Compiled Server Controls


While placing the code to access the HttpContext.Items Hashtable in each and every User Control and compiled server control will work, it's not ideal, since you have to repeat the code in each control. This is a poor choice for a couple reasons: first, you are tightly coupling the HttpContext.Items implementation to the User Controls/custom server controls, which would be a headache to have to change if you decided later not to use this approach; second, you have to have all of the User Controls and compiled custom controls agree on a same key name for the data they are caching (I used usersX in the example above). Having to remember the right name across all controls is, obviously, a recipe for bugs.A better approach is to move the HttpContext.Items-specific code outside of the User Controls and compiled controls. One option is to move it into the data access layer. In the GetUserByUserId(int) method, for example, we could do the caching like so:
... inside the data access layer ...

// C#
public static UserInfo GetUserByUserId(int userID)
{
  // See if User X is in the Items Hashtable
  UserInfo u = (UserInfo) HttpContext.Current.Items["user" + X.ToString()];
  if (u == null)
  {
    // get the user info from the database and populate a UserInfo class...
    u = new UserInfo();    
    ...    
  }
  
  return u;
}


' VB.NET...
Public Shared Function GetUserByUserId(userID as Integer) as UserInfo
  'See if User X is in the Items Hashtable
  Dim u as UserInfo = CType(HttpContext.Current.Items("user" & X), UserInfo)
  If u Is Nothing Then
    ' get the user info from the database and populate a UserInfo class...
    u = New UserInfo
    ...
  End If
  
  Return u
End Function
Note: To get this to work you will need to make sure you have added using System.Web or Imports System.Web into your data access class, and that the assembly has a reference to the System.Web.dll assembly.
The one disadvantage with this approach is that it ties your data access layer to a Web application, since the HttpContext object is only accessible when the data access layer is operating through a Web application. If you need to use your data access layer for WinForms-based applications as well, it would be a smarter move to create another tier in your architecture, a "Web application data access layer" that resided between your ASP.NET Web application and the data access layer. This middle tier would utilize the HttpContext.ItemsHashtable, thereby keeping the data access layer not tied to a particular application type.

Conclusion


In this article we examined how the HttpContext.Items Hashtable can be used as a per-request cache. This can offer improved performance for your ASP.NET application if you find that your pages have several User Controls, compiled controls, or custom business classes that each hit the database for the same (or similar) pieces of data. By using this per-request cache, you will only incur one trip to the database - for the redundant trips, the data can be quickly accessed from the Items Hashtable.Happy Programming!

  • By Scott Mitchell
  • Using HttpContext.Current.Items as a data storage for current HttpRequest

     - See more at: http://www.shubho.net/2011/01/using-httpcontextcurrentitems-as-data.html#sthash.c46lzi0n.dpuf

    Using HttpContext.Current.Items as a data storage for current HttpRequest


    DARE TO SHARE?
    Did you ever use HttpContext.Current.Items?

    Chances are there you didn't. Why? Because this is a least known thing which people talks about, but, this could be a good friend of you "in need". Let's see what this is and how this could be used effectively to carry out our works in better approach.

    When an HttpRequest arrives at an Asp.net application, the Request is processed and the result is usually served back to the browser (Or, client application) as HTML output. Since Asp.net receives the Request, it goes though lots of steps. For example, it could go though the following steps:
    • Application_BeginRequest in Global.asax (If defined)
    • Init event in custom HttpModules (If defined)
    • Page_Load other life cycle events events in a Page
    • Page_Load other life cycle events events in a Master Page
    • Page_Load and other life cycle events in User controls
    • Method invocation on Dlls
    While the Request is traversing through these steps, what if at step1 we have some data that we need to make available when the Request is traversing step2?

    Lets see some examples where we may need to implement such requirement:

    Example1

    Suppose, we have an Application_BeginRequest() event handler at Global.asax which is executed for each Request, and, we retrieve some data from somewhere within this method:

    ?
    1
    2
    3
    4
    void Application_BeginRequest(object sender, EventArgs e)
    {
        //Retrieve some data from somewhere for each Request
    }

    Now, we need to make sure that this data is available to the target Page which will get executed, to avoid to load the same data again in the Page. How would we pass the data to the Page?

    Example2

    Suppose, we have a user control which retrieves data from the database using an expensive operation. Once the user control finishes executing, the data is to be served to another user control which does some other stuff with the same data. How could we pass the data from this user control to another user control?

    Example3

    Perhaps we have some data at the Page_Load event (Say, current user object), which we need to make available to each and every method that get executed on the Business and Data access layers and we don't really want to modify each and every method to accept a new parameter just because we need to make the data commonly available to all methods. What do we do?

    I know, there are alternatives. We may use different approaches while we deal with each above examples. The easiest and most general approach which is being used in such cases is as follows:
    • Store the data in Session in Step1 
    • Retrieve the data from Session in Step2
    • Clear the data from Session in Step2 (Clear it because this Session data is not required for any other Request)
    Unfortunately, the Session state is being misused in such approach. Session should be used to store data which are required for the current Session, not for the current Request, and hence, this is not obviously a best practice to use in such cases. Also, if someone forgets to clear the data from the Session at Step2, a BUG is given birth to the system.

    Well, the good news is, HttpContext.Current.Items is the perfect solution for such scenario. This is a simple HashTable which lets you store and retrieve data as long as the HttpRequest is alive and traversing through different steps in its life cycle.

    So, you could use HttpContext.Current.Items to store data in one step and retrieve later in other step as follows:

    ?
    1
    2
    //Store data in Step1:
    HttpContext.Current.Items.Add("Key", "Value");

    ?
    1
    2
    //Retrieve data in Step2:
    object value = HttpContext.Current.Items["Key"];

    This HashTable could be considered as your Cache storage as long as the Request is being processed. This is a good friend indeed and be friend it with, and get benefited.
    - See more at: http://www.shubho.net/2011/01/using-httpcontextcurrentitems-as-data.html#sthash.c46lzi0n.dpuf