Stats, data, and answers, as to why there are so few women in technology fields.

Women today represent an abysmal percentage of the population of most STEM fields (Science, Technology, Engineering, and Math), and that number is shrinking, rather than expanding. At the same time, fewer young women are entering the STEM workforce than in previous years.

Why are women leaving STEM fields?

Researchers have been gathering volumes of data as to the why there are fewer women are staying in, or entering STEM fields, and from that data we can see many issues that cover a spectrum from that need to be addressed:

  • Sexism: overt and subtle (hostile macho cultures)
  • Harassment, threats, or potential or actual violence toward women
  • Childcare
  • Financial Independence
  • Gender Stereotyping
  • Work-life balance

Considering the number of challenges, addressing the lack of women in technology is a multifaceted phenomenon with no single solution, with each matter deserving attention. The primary goals of this post will focus on demonstrating…

  1. Incidents of sexism at industry events, and online conversations, and their link to the decline of women in STEM fields.
  2. The effects sexism has on women and the STEM industries as a whole, both now and in the future.
  3. A call to action to drive awareness and take a proactive stance in promoting women friendly STEM workplaces, conferences, schools, and meeting places.

By understanding these influences women in technology, particularly in software development, we can take corrective and proactive stances, in the retention, engagement, and attraction of top female talent.

Incidents of sexism are major contributors to a declining female STEM workforce.

The National Center for Women In Technology describes sexist incidents [.pdf] in various ways including,

“experienced/observed exclusionary cliques, unwanted sexual teasing, being bullied, and homophobic jokes”.

Consider that  between January and October 2011, women reported 20 sexist incidents to the Geek Feminism Wiki, with some common themes: 

  • Several talks at tech conferences contained pornographic style imagery, or sexual imagery.
  • Multiple presentations referenced women in a derogatory or demeaning way, (e.g., “women can’t program”, “women are stupid”) or by overt or subtle objectification of women.
  • Overt harassment, inappropriate touching, and groping are still commonplace at technical conferences.

Roughly one incident every two weeks this year means that this happens more than we’d like to think – and that’s only the reports from a single website.

Exclusionary, offensive, incidents at conferences, along with threats, violence, and harassment, against women in technology (and women in general) are simply not isolated occasions. They have profound implications that directly impact the declining numbers of women in technology. The Washington Post outlines some statistics demonstrating this, in a study on interactions between men and women during online chat sessions.

“A 2006 University of Maryland study on chat rooms found that female participants received 25 times as many sexually explicit and malicious messages as males. A 2005 study by the Pew Internet & American Life Project found that the proportion of Internet users who took part in chats and discussion groups plunged from 28 percent in 2000 to 17 percent in 2005, entirely because of the exodus of women.” [emphasis mine]

Those numbers have barely improved, five years later. Additionally, the participants in this study belong to a general online audience and not solely the STEM fields, so one must consider the fact that STEM fields are male dominated, resulting in a larger amount of sexist behavior.

Though not the only reason, the numbers show that in software development specifically, sexist and overtly offensive behavior (both online and off) is one of two key factors as to why women are leaving technical fields as reported by ABC News. This article quotes Laura Sherbin, director at the Center for Work-Life Policy, who published a study in the Harvard Business Review titled “Reversing the Brain Drain in Science, Engineering, and Technology”. Laura goes on to explain the primary reasons women leave STEM fields…

“The top two reasons why women leave are the hostile macho cultures — the hard hat culture of engineering, the geek culture of technology or the lab culture of science … and extreme work pressures”

Sherbin also highlights just how critical and surprising the numbers are, even to researchers.

“The dropping out was a surprise to us. We knew anecdotally that women were leaving these careers. We didn’t expect to see the number 52 percent.”

To reiterate: 52% or just over half, of the female STEM workforce leaves because of hostile macho cultures.

Let’s do the math:

  • Assume the average tech conference has 300 attendees.
  • The average turnout of females at a technical conference is at about 15%, or 45 women in this example.
  • 52%, or 23 of the women at that event will leave the industry[1].
  • At a rate approximately of 26 events per year affecting 23 women each time, 598 women will be subjected to a hostile environment each year[1].

The cost in human terms and individual well-being is immeasurable.

A look at the negative effects and human cost of sexist behavior in STEM fields.

Considering the above numbers, try out this thought exercise, showing the implications of sexist incidents on women in software.

  1. Think of the names 23 women developers that you work alongside, have worked with, or know. Try it without looking at social networks, checking address books, etc…
  2. Think about these women. Are they your coworkers? Presenters you admire? Are they women with whom you enjoy having technical conversations, perhaps at conferences, code camps, or over social networks?
  3. There’s essentially a 50/50 chance, or the same chance as the toss of a coin, that those 23 women won’t be developers for much longer.

Once they’re gone, can you name 23 more women to replace them? It won’t be the younger girls entering the field.

The consequences have a stifling effect on younger girls wanting to enter the technology fields before they have a chance to start. Numbers show that a huge impasse in attracting young girls into the STEM fields, is a serious lack of women role models in those fields. Less women staying in the field means fewer role models for young girls, which in turn means fewer STEM girls overall.

It’s not just about sexist incidents though, subtle sexism can bleed into the everyday atmosphere of in tech fields and cause the same amount of negative barriers. While the day to day activ
ities of most technical women might not vary much from that of men, as far as actual programming, sitting in meetings, mundane business tasks, etc… What do differ are the interactions between the sexes, as well as both overt and subconscious behavior that manifests as sexist incidents, though primarily non-malicious, and most often subconscious. For example, here are some commonplace scenarios where subtle sexism happens in companies large and small[2][3]:

  • Men who repeatedly ask only the women attending meeting to take notes, or get coffee, when the woman is not a secretary or in a similar role.
  • Colleagues that routinely ignore women during meetings, or a female states an idea that is promptly ignored, then raised again by a man who gets the credit. (in a consistent, frequent, pattern)
  • Women, rather than men, are routinely stuck into “softer” positions, often to answer phones. Management gives women more remedial tasks that are clearly not aligned with their job description or what they were hired to do.

The sentiments above are detailed in a report by Level Playing Field Institute titled “The Tilted Playing Field: Hidden bias in information technology workspaces”  [.pdf]. Reading about recent events and stories of everything from demeaning comments, to outright harassment, stalking, and groping, are still commonplace in the tech industry. I must agree that I’ve personally been privy to a number of these types of scenarios, but that’s not all…

When an incident at a conference happens, I inevitably get a call or email from a female colleague who has just given up, and is now looking at non-technical career alternatives.

If we are to keep our technical industries healthy, and full of diverse creativity, things must change, and soon. So what can you do?

A Call to Action: Drive awareness and take the lead to promote diversity in STEM fields.

Below are just some of the things you can do to drive diversity and promote women in STEM fields:

Drive awareness.

It may seem obvious, but without awareness, it’s impossible to know there’s a problem.

You can drive awareness by blogging, tweeting, or otherwise telling your story, or commenting on blogs to show your support. The Level Playing field’s report shows a real lack of awareness in populations at large. The more blog posts, articles, and events, mean more information people can use to take proactive stances to create technical communities and workspaces that are welcoming to everyone.

Be proactive.

  • Does your company have a diversity and inclusion policy? Even if you work for a small business or startup, a formal policy of inclusion fosters a welcoming environment for everyone. If you company doesn’t have one, get involved and ask your HR department to work on one with you. Don’t let your policy be a paper form of lip service, make it part of how you do business.
  • Does your HR department have a clear open door policy, with a trusted employee to listen to concerns?
  • Attend women in technology events. Hint: Take your favorite gal developer with you. At the Code Camp NYC 2011 WIT luncheon, a healthy mix of men and women joined in for a productive, round-table discussion.
  • Ask technical women work on a joint talk with you for a user group or code camp, and invite them to technical events.

Awesome guys like John Zablocki and coworkers like Joe Healy, Peter Laudati, and Brian Prince, are just a few of the many guys I see at WIT related events.

Presenters & conference organizers:

Speakers can use the Windows Phone 7 app content guidelines, or the Android app marketplace rating guide when s/he’s not sure what material should be considered offensive.

Organizers can create written guidelines to ensure a harassment-free environment for everyone at your conference, user group, or other meeting.

CodeStock 2010 set a perfect example to follow by embracing a WIT centered theme, including a female keynote speaker (*ahem* that would be me 🙂 ).

Summary

I would love to see every company behave as MS DPE East does, and I hope that you, dear readers of this blog, will step up to foster an environment in your workplaces and homes that support and celebrate women and diversity in STEM fields.

Should an incident occur at an event you’re attending, take corrective action as soon as possible. If you’re in a conference session and you feel offended or uncomfortable, walk out calmly, and write down exactly what you feel is offensive or inappropriate. Take the evaluation to the conference staff, and ask that they check out the session in question.

[1] The numbers in this sample represent one source of reports, so the actual numbers are much higher. Additionally, the number 23 is rounded from 23.4. Also assuming a single track conference, which is fairly common.

[2] These aren’t just manufactured scenarios – they’re real life stories from female contemporaries.

[3] As for large companies, my experiences at Microsoft DPE have been great!. I work on an highly functioning team with awesome people who celebrate diversity in technology and are quite supportive of each other.

Add HTML5 Geolocation plus Bing Maps into ASP.NET MVC views

The Bing Maps API is a free, easy to use API, that allows you to incorporate mapping features into your ASP.NET MVC or application by using Web standards such as JavaScript, and the now supported HTML5 Geolocation.

Bing Maps and ASP.NET MVC

A Bing maps API key is required when using the API. The Bing Maps key allows you to access Geolocation data, and to manipulate an in-view Map object with JavaScript via the Bing Maps API. The Bing Maps Developer Portal is where you can get a key by registering with your Windows Live ID.

Once you’re set with a key, you’ll need these files in your MVC project to develop with Bing Maps:

ScriptsYourBingMapsScript.js – This file contains your script that works with Bing Maps & Geolocation.

ContentSite.css – A small bit of CSS is required to style the Map

ViewsBingMapsIndex.cshtml – The MVC view that contains the Bing Map HTML

Since the code is HTML &CSS that conform to Web standards, the bulk of the lives is in the .js file and/or the view. Although using MVC, the model and controller are not necessary for manipulating maps with client side script, but don’t throw out the model and controller yet, as you will need them to work with other data.

The Bing Maps Interactive SDK

If you’re writing code that uses Bing Maps, the Interactive Bing Maps SDK is a “must visit” Web site. By choosing the options on the left of the page, the Bing Maps Interactive SDK creates usable JavaScript, and a “View HTML ” button that exposes the page source.

 

image_2

The Bing Maps API & SDK contain more than an interactive website. Bing Maps development gives you access to many productive development tools such as:

  • The Bing Maps AJAX Control (multiple versions)
  • The Bing Maps iOS Control
  • A Bing Maps Silverlight Control
  • SOAP and REST services
  • More…

You can use the Bing Maps Interactive API to create the equivalent code as the samples shown in this post.

Render Bing Maps in MVC views with the Bing Maps AJAX control.

While it’s called the Bing Maps AJAX control, it’s not a control at all, but a JavaScript library instead. HTML and client side script (JavaScript, jQuery, etc…) are the enabling technologies for Bing Maps on the ASP.NET (or any Web) platform. To reference the Bing Maps AJAX Control, your view needs the <script> reference below.

<script src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0" type="text/javascript"></script>

If you plan to use the Bing Maps AJAX control in multiple views, the <script> reference can go in the _Layout.cshtml file, otherwise you can add it to the required views or a different layout page. Inside a view, a <div> element should contain and display the map, and is also the DOM object that you manipulate in code, so it needs an id attribute.

<div id="map"></div>
Since the browser renders a tiny <div> by default, some CSS is necessary, such as the position, width, and height, in which to create a suitable DOM shape for maps. You can save the CSS in the ContentSite.css file, or its own file, for reusability across views.  
<style>
#map
{
    position:relative; 
    width: 500px; 
    height: 500px; 
    border:0px
}
</style>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

After the HTML is in place, you can write code to capture the user's positional data to display a Bing map showing the location, nearby restaurants, or other information requested by the user. 

Display a Bing Map with a Pushpin.

You first need positional data from the user before displaying the map. Once you have the positional data points, i.e., latitude and longitude, you can add a Bing Map to any MVC view. To learn how to obtain positional data for your Web site or app, see this post on creating location aware Web sites with the HTML5 Geolocation.

The code below retrieves the latitude and longitude coordinates from the position argument of a showMap method, then creates an instance of a Map object the position, credentials, center, map type, and zoom level. The code continues on by centering the Pushpin to represent the user’s location in the map.

function showMap(position) {
 
    var latitude = position.coords.latitude;
    var longitude = position.coords.longitude;
 
    var map = new Microsoft.Maps.Map($("#map")[0],
    { 
        credentials: "Your Bing Maps API Key",
        center: new Microsoft.Maps.Location(latitude, longitude),
        mapTypeId:   Microsoft.Maps.MapTypeId.road,
        zoom:        10
    });   
 
    var center = map.getCenter();
    var pin = new Microsoft.Maps.Pushpin(center, { width: 50, height: 50, draggable: false });
    map.entities.push(pin);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The result should look something like this (but with your coordinates):

SNAGHTML1015b426

Should you want to customize the Pushpin icon, just change the Pushpin construction arguments, and pass in the path and name of the graphics file (.png, .jpg., and standard Web formats).

var pin = new Microsoft.Maps.Pushpin(center, {icon: 'CustomPushpin.png', width: 50, height: 50, draggable: true}); 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Customizing the map further by adding an Infobox, which is a small rectangle with information about a particular location, takes only a few lines of code. Make sure the clear method is run before pushing an Infobox onto a map or the latest Infobox, Pushpin, or other object will overlay the previous.

 map.entities.clear(); 
 var infoboxOptions = {title:'Bing Maps Rock!', description:'Add an Infobox to a map with very little JavaScript!'}; 
 var defaultInfobox = new Microsoft.Maps.Infobox(map.getCenter(), infoboxOptions );    
 map.entities.push(defaultInfobox);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The above code creates an Infobox on the map similar to the one shown here:

SNAGHTML101866d1 

These are just a few simple, but core examples, of what you can do with Bing Maps. For more information on developing for Bing Maps, see below in the Summary & Resources.

Summary & Resources

The Bing Maps AJAX control is a handy library you can use to add geo-interactivity to your Web sites with little code. Additionally, you can incorporate other APIs to make full featured location aware mapping apps.

Use the W3C Geolocation API to create location aware Web sites

The Bings Map control (Bing Maps API)

Bing Maps Articles

Customizing Bing Maps Pushpins

G. Andrew Duthie demonstrates bing maps in action with CommunityMegaphone.com

ASP.NET MVC ActionResults explained

Action results are an important part of the ASP.NET MVC controller system, and definitely worth taking a good look at. Understanding how they work gives you many more choices in MVC and that will certainly help make your code better.

What is an ActionResult?

An ActionResult is a return type of a controller method, also called an action method, and serves as the base class for *Result classes. Action methods return models to views, file streams, redirect to other controllers, or whatever is necessary for the task at hand. The controller takes on this responsibility to connect system components, acting as a traffic cop.

There are many derived ActionResult types you can use to return results that are more specific for a particular view. You can quickly access the derived types of the ActionResult during development by hovering over an ActionResult in an action result’s method signature then expanding the type tool window, to see what *Results the ASP.NET Framework provides.To get a deeper look at what exactly an ActionResult type is and how it works, running the code with a breakpoint set at the end of an action result method will get the information we want. Inspecting the image below of the Watch window shows some of the properties that you can tap into that ActionResults return.

Notice the Model, TempData, ViewBag, and ViewData properties. Drilling into the Watch window even further exposes the Model property’s strongly typed collection of objects.

SNAGHTML4d9b785_thumb3_2

These objects contain everything you need when working in the view. Of course, the Model is the most heavily used object, containing our application’s schema and data. The TempData object holds data between multiple controllers, while ViewBag and ViewData objects holds data between controllers and/or views.

Since the Model property is the actual model the view uses to render the data, its data type should align with the type specified in the @model directive in the target view. As pointed out in the image above, the Model property contains a strongly typed list of Product objects (or whatever you’re returning), matching the view’s model.

Looking in the Watch window shows that the runtime converts the ActionResult to a ViewResult, however you’ll want to be more specific during design time. Swapping ActionResults for more specific/derived classes, for example, a ViewResult, produce the exact same object structure as the ActionResult. With this in mind, using more specific types increases code accuracy, maintainability, and even performance as the compiler has a much better idea of what should happen at compile time, rather than at the last minute at runtime, since no runtime conversion happens.

Action methods, action results & routing

Action methods and the routing system work together in every MVC application. MVC does this by using a set of conventions, defined as routing patterns in the global.asax.cs file. These patterns connect HTTP requests with controllers and action methods. As an HTTP Request enters the routing system, it determines which controller should serve data to which view (if any).

The global.asax.cs defines the default routing pattern, {controller}/{action}/{id}, as described in more detail here:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
    );
}

Picking apart each piece of the route pattern is a great way to digest what the routing system is doing…

  • {controller} Controller maps a part of the URL to the name of the controller class. For example, a class named ProductsController, will map to URLs that start with /Products (after the domain of course). ASP.NET automatically drops the word “Controller” from the URL so is it’s more user friendly, e.g., /Products vs. /ProductsController.
  • {action} Action maps a part of the URL to the individual methods inside controllers. Therefore the ProductsController.Edit(…) and ProductsController.Details(…) methods align with the /Products/Edit and Products/Details URLs, respectively. Action maps without any parameters, since the next route pattern, id, defines them.
  • {id} Id maps to an identifier, such as a product id or a product name. These are controller action method parameters, so the value at the end of the URL is generally the value of the method’s argument. For example, /Products/Edit/2 matches up with the id argument in ProductsController.Edit(int id). The controller methods normally use this id to query for a single record with a matching id to return to the view.

Below is a table detailing the mappings between routes, controllers, action methods and their parameters.

Action Method Route {controller}/{action}/{id} HTTP POST/GET
public ActionResult Index() { } /Products GET
public ActionResult Details(int id) { } /Products/Details/id GET, values in URL
public ActionResult Edit(int id) { } /Products/Edit/id GET, values in URL
[HttpPost]
public ActionResult Edit(int id, FormCollection collection) { }
/Products/Edit/id POST, values in FormCollection
public ActionResult Create() { } /Products/Create GET
[HttpPost]
public ActionResult Create(FormCollection collection) { }
/Products/Create POST, values in FormCollection
public ActionResult Delete(int id) { } /Products/Delete/id GET, values in URL
[HttpPost]
public ActionResult Delete(int d, FormCollection collection) { }
/Products/Delete/id POST, values in FormCollection

You may have noticed that the Edit, Create, and Delete action methods come overloaded as pairs, and an [HttpPost] attribute decorates one method in each pair. Since [HttpGet] is the default, the other method doesn’t need to be marked. Additionally, all methods decorated with the [HttpPost] attribute are meant to accept HTML input fields located between the <form> tags. The collection parameter of type FormCollection[1] contains all the input fields from the <form> of the HTTP Post.

Every method in a controller class returns an ActionResult by default; however, some actions will be more optimized, clear, or accurate in the code, if we are to specify a more specific action results, for instance, a ViewResult, rather than an ActionResult. Action result methods can also designate that its result will return something other than data for a view, e.g., a HttpNotFoundResult or an HttpStatusCodeResult, as shown in the code below:

Returns an HTTP 404 Not found error:

public HttpStatusCodeResult NotFound()
{
    var result = new HttpStatusCodeResult(404);
    return result;
}

Redirects to a separate view altogether:

[HttpPost]
public RedirectResult Create(FormCollection collection)
{
    // code to save form data ...     
    return new RedirectResult("Home/Index", false);
}

There’s many more ActionResult types to explore. Check them out and find something that meets the needs of your controller and/or view.

Summary

ActionResults are a key component to ASP.NET MVC, so understanding them is essential for MVC application development. Whether you need to make AJAX calls, redirect, return a file stream, or just return data to a view, ActionResults are right there in the center of all the……action.

[1] I recommend rather than using FormCollection, you should use a strongly typed parameter or multiple, differently typed parameters that match to data types in the HTML form. Look forward to a blog post soon to demonstrate this.

Building a relational data model in ASP.NET MVC w/EF Code First

Just about every application uses some sort of data model, and .NET developers have been using POCOs (Plain Old CLR Objects) for some time now. You can use either new or existing POCOs in MVC 3 applications and still take advantage of EF (Entity Framework), and in particular, EF’s Code First feature. EF’s Code First feature allows you to base both an application and a database from your data model. EF additionally carries features for database and model first development.

Data Models, ORMs & Entity Framework

As with most business apps of any type, data models are at the heart of an application. When developing ASP.NET MVC applications it’s best to go with an ORM (Object-Relational Mapper) such as EF, as ORMs alleviate many pains in dealing with databases and their objects. Since MVC is extensible and pluggable, you also have the choice of using 3rd party or open source ORMs, for example, the widely used nHibernate.

That’s where things can get complex, and that’s where EF fits in with multiple strategies to help alleviate common pains in modeling. There are many ways you can model data to represent and manipulate it the way you need to, either visually with a designer, or by using code. EF supports these data access options:

  • Database first
    • You can use Visual Studio to connect to a data source and visually generate a data model from an existing database(s).
  • Model first
    • Using model first you can build brand new databases from models you’ve created using the designers in Visual Studio.
  • Code First
    • With code first, you start with your own POCOs, just add a small amount of code, and voilà, instant ORM.

In addition to these features, EF has more advanced features, such as a XML based schema mappings and fluent APIs. EF is flexible enough to cover the spectrum of applications from the smallest of web sites to enterprise applications.

Before coding EF classes, you must add a NuGet package reference to EntityFramework by selecting “Add Library Package Reference” from the Project menu, and before using SQL CE 4.0 you’ll need to add a regular reference to the System.Data.SqlServerCe library.

Building the basic data model

Code First is a feature of EF that maps POCOs containing classes, relationships, data annotations, etc…, to database tables, columns, constraints, and relationships in physical databases. EF CF creates the database by examining the code in the data model, then building the corresponding physical database and its objects. You have the option to merge or drop/recreate any databases generated by EF Code First, and you can additionally seed the database with  data (coming in a later post).

Since the controller returns the model to the view, you can send validation information to the view by using Data Annotations. Data annotations are attributes that you can apply to a model to perform common types of validation at the property level, as shown below in two basic POCO classes.

public class Category

{

    public int Id { get; set; }

 

    [DisplayName("Category")]

    [Required(ErrorMessage = "The product category is required.")]

    public string Name { get; set; }

}

public class Product

{

    public int Id { get; set; }

 

    [DisplayName("Delicious Treat")]

    [Required(ErrorMessage = "The product name field is required.")]

    public string Name { get; set; }

 

    [Required(ErrorMessage = "The product description field is required.")]

    public string Description { get; set; }

 

    [DisplayName("Sale Price")]

    [Required(ErrorMessage = "The Sale Price field is required.")]

    public decimal Price { get; set; }

 

    [DisplayName("Made fresh on")]

    [Required(ErrorMessage = "The Freshly Baked On field is required.")]

    public DateTime CreationDate { get; set; }

 

    [DisplayName("Don't Sell After")]

    [Required(ErrorMessage = "The Expiration Date field is required.")]

    public DateTime ExpirationDate { get; set; }

 

    [DisplayName("Qty Available")]

    [Required(ErrorMessage = "The Qty Available field is required.")]

    [Range(0, 120,ErrorMessage="The Qty Available must be between 0 and 120.")]

    public int QtyOnHand { get; set; }

 

    [DisplayName("Product Image")]

    public string ImageName { get; set; }

}

Now that you have a model, you can add a few lines of code to tell EF to generate the database for you, and even seed it with data if you want to. In order for EF to know what classes in a project it should use as a model to generate the database, you need to tap into two classes from the System.Data.Entity namespace:

  • DBContext class.
    • The DbContext is a lot like a connection, except it manages database connectivity for you automatically (i.e., no need to explicitly call open/close on connections). Additionally, there are many properties methods on the DbContext class to work directly with the model and/or database, such as the SaveChanges method or the ValidateEntity method.
  • DbSet class
    • This object knows how to deal with CRUD operations on the entity class itself (i.e., Category or Product), and works in tandem with the DbContext object to perform those operations.

A data model is not just a set of POCO classes, though. Models need a class to manage the POCOs, perform connection management, or other duties that an ORM would do. These management classes are often called a context or repository[1]. Rather than writing the database and connection management code yourself, you can take advantage of EF and receive features provided automatically by inheriting from the DbContext class in your repository class.

The DbContext also needs to know what POCO collections to work with. You can do this by adding properties of type DbSet<T> for each of your collection types, as the code below demonstrates.

public class FourthCoffeeWebContext : DbContext

{

    public DbSet<Category> Categories { get; set; }

    public DbSet<Product> Products { get; set; }

}

At this point, the two POCO classes and DbContext are all you need to see EF in action, and you can move onto running the application and generating the physical database.

Generating the database from the model

Assuming you have the controllers and views in place to perform CRUD operations on the Categories and Products collections, running the MVC application will create a SQL (Express or CE 4.0) database automatically for you. Of course, there’s no data, just the schema, but the site and database are both up, running, and completely functional. Navigating to the create action on the products controller in a browser renders the create view like the one below (including validation!):

 

image_6

 

Once you save a product, the app takes you back to the listing of products, where you can see the results.

image_8

Although you can see the data on in the browser, you probably can’t find the database in the Solution Explorer. Checking out the customary App_Data folder reveals nothing, and examining the Web.Config file comes up empty. Since EF could find no information about the database, it created a SQL Express[2] database with the a default name and path shown here:

C:Program FilesMicrosoft SQL ServerMSSQL10_50.SQLEXPRESSMSSQLDATAFourthCoffee.Web.Models.FourthCoffeeWebContext.mdf.

If you want to name your database something different, modify the <connectionStrings> section of the Web.Config file to point to the preferred database name and location. This connection string connects to the App_Databakery.sdf database.

<connectionStrings>  

  <add name="FourthCoffeeWebContext" connectionString="Data Source=|DataDirectory|bakery.sdf" 

  providerName="System.Data.SqlServerCe.4.0" />

</connectionStrings>

By convention, the name of this connection string needs to match the name of your context/repository class, in this case, FourthCoffeeWebContext, so EF can identify the connection string to use. Notice that the connection string points to the data directory (App_Data) and it’s a SQL CE 4.0 database. If you wish to use a different edition of SQL, feel free to change the connection string and provider name to point to other locations.

Once the changes are in place, run the application, enter some data, and return to Visual Studio where you can see the App_Data folder now contains the bakery.sdf database.

image_10

Since the option to drop and recreate the database exists, you can design your data model through code and tests to verify that it works in a repetitive cycle, so relating the classes and regenerating the database is easy.

Relating classes in the data model

The Category and Product classes relate to each other in a one-(zero or)many relationship. You can express this relationship in code by adding a property in the Category class to represent the collection of related products, as shown here:

public virtual ICollection<Product> Products { get; set; }

The Product class needs two lines of code, so you’ll need to add the following properties below to the Product class.

public int CategoryId { get; set; }

public virtual Category Category { get; set; }

While the data model is complete, the code in controllers and views does not reflect the updates made to the model. The Edit and Create views associated with the Product need to include a dropdown of the categories, with the current product’s category selected, similar to the code below:

class="editor-label">

    Category

class="editor-field">

    @Html.DropDownListFor(model => model.CategoryId, 

    ((IEnumerable)ViewBag.PossibleCategories)

        .Select(option => new SelectListItem {

        Text = (option == null ? "None" : option.Name), 

        Value = option.Id.ToString(),

        Selected = (Model != null) && (option.Id == Model.CategoryId)

    }), "Choose...")

    @Html.ValidationMessageFor(model => model.CategoryId)