Friday, December 28, 2012

Getting Started With Entity Framework 4.3.1

Introduction
Entity Framework (EF) has evolved quite a bit and as it has evolved it has become more and more confusing to keep up with its changes which have been introduced a series of addons in the form of libraries. You can sit down and read pages of documentation to understand what has happened, but when you just need to dive into something because of time constraints it is frustrating. That has led me to ask the question "How do I install and use EF 4.3.1?" Well unfortunately it is not a one click install, it is a multi-step installation.

Assumptions
  • You are using Visual Studio 2010
  • You are using the .Net 4.0 Framework
  • You need to either create a new EDMX or you have an existing EDMX using the stock version of EF that comes with .Net 4.0 and VS2010 which is EF 4.0
  • You are using the database first method (versus code first method)
  • You have NuGet installed (this is required)
  • You have made a backup of your project before continuing (just in case things go sideways)
Can I used EF 5.0 instead?
If you are using Visual Studio 2010 (VS2010), then the answer is NO. EF 5.0 is supported in Visual Studio 2012 (VS2012) for .Net 4.5, if you have access to VS2012 then I say go for it. I haven't had a chance to move on yet myself.

Part A: Setting up a Project with an EDMX file
  1. If you don't already have an EDMX file, then either create a new project or use an existing one, and add a new item to your project (Right click on project file > Add > New Item...)
  2. Under "Installed Templates" (left hand side) select "Data" and then select ADO.Net Entity Data Model - name it however you see fit. Example: InventoryModel.edmx
  3. Follow the wizard and setup your edmx as you would normally - add which ever tables you need etc...
  4. After you have finished adding your edmx, it is time to install EF 4.3.1
Step 1

Step 2-4

Part B: Installing EF 4.3.1
Reminder: You must have NuGet installed to perform these steps
  1. Open up the NuGet Package Manager Console: Tools > Library Package Manager > Package Manager Console
  2. Make sure you have the correct project selected and at the command prompt enter the following command sans soft quotes: "Install-Package EntityFramework -Version 4.3.1" Where did you find this command? After pressing the enter key a bunch of stuff happens. Some of that stuff is a dll named "EntityFramework" is added a dll reference to your project. If you haven't used NuGet before then don't be alarmed by the config file named "packages.config", that is added when adding packages using NuGet.

Step 1

Step 2

Verification 1

Verification 2
Part C: Using EF 4.3.1 and a DBConext Generator of your Choosing
Say hello to the System.Data.Entity.DBContext Pattern, this is essentially what you have enabled yourself to use by installing EF 4.3.1, there are a number of new properties and awesome methods that have been added to the DBContext pattern. You are switching over from the System.Data.Objects.ObjectContext pattern which comes stock with EF 4.0 in VS2010.

Context Generators
You should use the right context generator for the job and each context generator has its own quirks. Really the defining line in my opinion on which context generator to use is by asking yourself, "Do I need to have an SOA or am I going to use WCF?" If the answer is yes, then you want to use a context generator with WCF support. If the answer is no, or you don't mind writing your own translation layer (converting your entities to POCO manually) then you can just use the regular DbContext Generator.

For argument's sake, we are going to use the DbContext Generator since it is basically the next step up from the original ObjectContext generator. It will not generate serializable objects, so don't bother with it for WCF.
  1. Add a new Code Generation Item by opening your EDMX file > right click on blank space > select "Add Code Generation Item..."
  2. Click on Online Templates located on the lower left hand side of the left pane.
  3. Click on "EF 4.x DbContext Generator for C#"
  4. Name it something different from your EDMX, like "DummyDBCModel.tt"
  5. Press the Add button - automatically this model will generate one file per entity and your old ObjectContext will no longer be valid. You will now have to use the new DbContext for any existing code (if you had any).

Step 1

Step 2-5
What Now?
You are probably thinking, "Okay great, I upgraded from 4.0 to 4.3.1, but what can I do that I couldn't do before?", well right off the bat there are two very useful things that I can name. There is now a Database Property, that will easily allow you to get your connection string, not too exciting, but not bad either. The second and most valuable thing in my opinion is the ability to selectively update fields/properties/columns when making an update to an entity.

I Upgraded and Everything is Broken Now!
If you were upgrading an existing project from EF 4.0 to 4.3.1, then yes, there is a good chance a lot of your code will be broken because the 4.0 syntax is different from the 4.3.1 syntax, but the idea remains the same it is still an ORM. For example in 4.0 using the ObjectContext to do an insert into a collection of Books you would write: context.Books.AddObject(book); but in 4.3.1 using the DBContext you will write context.Books.Add(book); - not a major difference, just syntactically different.

Useful Code Snippets
Here are some useful code snippets, specifically extension methods, for stuff you are probably going to do one way or another.

Code
using System.Data.Entity;
using System.Data.Entity.Infrastructure;

/// <summary>
/// Get the connection string from the provided DbContext
/// </summary>
/// <param name="context">the target context</param>
/// <returns>the connection string this context is using</returns>
public static string GetConnectionString(this DbContext context)
{
 return context.Database.Connection.ConnectionString;
}

/// <summary>
/// Insert the entity of type T into the appropriate entity collection of type T
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
public static void Insert<T>(this DbContext context, T entityObject) where T : class
{
 context.Set<T>().Add(entityObject);
 context.SaveChanges();
}

/// <summary>
/// Update an entity of type T and only update the specified properties
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
/// <param name="properties">a strict list of properties to update</param>
public static void Update<T>(this DbContext context, T entityObject, params string[] properties) where T : class
{
 context.Set<T>().Attach(entityObject); //Attach to the context

 var entry = context.Entry(entityObject); //Get the Entry for this entity

 //Mark each property provided as modified. All properties are initially 
 //assumed to be false - further more properties cannot be marked as false, 
 //this is sadly a limitation of EF 4.3.1
 foreach (string name in properties)
  entry.Property(name).IsModified = true;

 context.SaveChanges();
}

/// <summary>
/// Mark an entity of type T as deleted. This is lazy deletion aka soft deletion. This method should only be used
/// if the entity has a Boolean Property named "Deleted".
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
public static void SoftDelete<T>(this DbContext context, T entityObject) where T : class
{
 //This method is the equivalent of setting the "Deleted" property to true and saving changes. 
 //Essentially this is a single property update.
 context.Set<T>().Attach(entityObject);

 var entry = context.Entry(entityObject);
 
 DbPropertyEntry p = entry.Property("Deleted");

 p.CurrentValue = true; //Mark this as deleted
 p.IsModified = true; //Mark this as modified

 context.SaveChanges();
}

/// <summary>
/// Permanently delete/remove an entity of Type T from it's corresponding entity collection.
/// </summary>
/// <typeparam name="T">an entity of type T</typeparam>
/// <param name="context"></param>
/// <param name="entityObject">an entity of type T</param>
public static void HardDelete<T>(this DbContext context, T entityObject) where T : class
{
 context.Set<T>().Attach(entityObject);
 context.Set<T>().Remove(entityObject);
 context.SaveChanges();
}

Usage Examples
using (TestDumpEntities context = new TestDumpEntities())
{
 Book obj = new Book();

 context.Insert(obj);

 obj.AuthorID = 10;
 obj.BookName = "A Walk in the Life of Foo";

 //Only update BookName, even though AuthorID was modified too.
 context.Update(obj, "BookName");

 context.SoftDelete(obj); //Set obj.Delete = true and update in the DB

 context.HardDelete(obj); //Complete remove this entity from the DB

 Console.WriteLine(context.GetConnectionString()); //Print out the connection string
}

DbContext Generator with WCF Support
If you require WCF support, then I strongly suggest using the DBContext Generator with WCF Support as opposed to the POCO generator. The classes that are generated are lightweight, so much so that you lose a little bit of functionality unfortunately. With the regular DbContext Generator when you load an entity, any relational properties (collections of other entities related by Foreign Key), those relational properties are loaded for you. With the DbContext Generator with WCF Support, those relational properties are not loaded for you, you have to explicitly state that you want them loaded in your lambda expressions or linq queries.

How to Explicitly Load a Relational Property
For demonstration purposes, let's say we have a Author and Book entities. Authors write multiple Books and therefore the Author Entity has a List<Book> property named Books. (Author.Books) - this is done in the database by taking the Author's Primary Key (PK) AuthorID and placing it as a Foreign Key (FK) in the Book table, also named AuthorID. An explicit FK relationship is created in the DB. This is construed as a Relational Property automatically by EF when generating the entities for the model. If you do not explicitly load the this property it will be empty. Therefore to achieve this do the following:

using System.Data.Entity;
using System.Linq;

//Example of returning a list of Author and loading each Author's Books property with their Books
using (TestDumpEntities context = new TestDumpEntities())
{
 return context.Authors
      .Where(x => x.AuthorID == 1)
      .Include(x => x.Books) //This will load your books for you
      .ToList();
}

Enjoy

Saturday, December 8, 2012

Sprinkler System Pump Assembly Demystified

Background
You are probably wondering to yourself - why the hell are you posting this? Trust me - there are like no articles about this on the net that I could find when I needed them, so I am going to fix that right now. Putting in a sprinkler system pump is not nearly as easy as it sounds, especially when every guide you find on the net assumes that you are using a lake or a city line as your water supply. Well I have a well, that is my water source, I couldn't find any info on this. Now that I have the experience I want to share it with who ever is looking for it.

Assumptions
  • I am assuming you have trenched your sprinkler system's lines already, you just need to install your sprinkler pump next to the well's spigot (outlet or water source). For this example, I am going to assume two zones, if you have more zones, that's fine - you just need to get yourself the appropriate indexing valve.
  • I am assuming you are using a centrifugal pump.
  • I am assuming you are using a well or body of water as your water source and not a city connection. City connections do not generally require pumps since they have enough pressure - they usually only require a relay/solenoid assembly.
  • I am assuming that you have had an electrician connect your timer at the appropriate voltage and amperage specifications. Pumps generally run at 120 VAC @ 20 A or 220 VAC @ 10 A. You must choose which configuration you want so that you can purchase a timer that can support it. Remember your timer must support the peak amperes specified by the pump otherwise you will burn out the timer.
Considerations
Make sure to draw out your design and take measurements between all points. That means measure between your well spigot and the pump and measure between the pump and where the indexing valve is or will end up.

Two Zone Cam for Four Zone Indexing Valve Gotcha
If you are going to use a four zone indexing valve for only two zones, make sure to purchase the indexing valve before placing the zone pipes so you can plan where those pipes will go; because the configuration of the two zone cam for the indexing valve will assume two of the exit points on the indexing valve (gotcha!). You are stuck with it unless you modify the cam (like I did) which I do not recommend! It is a total pain in the ass and I learned this the hard way. Planning is key here!

Part's List
This is the list of parts I needed, depending on your configuration, you might need something different - but most of these are necessary for all installations.
  1. PVC pipe typically 1-1/2" Schedule 40
  2. Check Flow Valve that has threads to fit 1-1/2" threaded couplers
  3. Threaded couplers 1-1/2" for all points that are not going to be glued.
  4. Teflon Tape (Blue Cap for liquid such as water - NOT THE RED ONE THAT IS FOR GASES ONLY)
  5. Pipe Thread Sealant (Tube of Yellow Goo)
  6. PVC Primer (bad smelling purple stuff)
  7. PVC Cement (clear goo that melts/fuses PVC together)
  8. Gloves (Latex, Nitryle etc...thin enough for grip) for when dealing with the PVC Primer and Cement, you do NOT want this shit on your hands, trust me. It is quite corrosive and will stain your skin and anything else it touches.
  9. Pressure Gauge for your pump and any sizing (up or down) adapters required
  10. Ball or Gate Valve for maintenance and for switching zones on the fly
  11. Indexing valve (4 zones in this example) which is not 100% required, this is only if you are going to use a timer or if you want to change zones a little easier. The alternative is to make a solid connection using a Tee fitting. You can control your zones manually using additional ball/gate valves.
  12. Two 3/4" Valve, one for the well and one for the pump. This is for priming your well and your pump.
  13. Any other parts to get the job done, couplers etc... Maybe some concrete blocks (8x4x16) for the pump to sit on.
  14. Tools you will need:
    • A. Hack Saw, fine tooth blade (metal blade)
    • B. Reciprocating Saw or equivalent - fine tooth blade (metal blade)
    • C. Pipe wrench (and a rag to cover the PVC with to avoid scratching it)
    • D. Knife or box knife
    • E. Crescent Wrench  
    • F. PVC Pipe Cutter (Not necessary - hack saw works just fine)
    • G. Reamer (Not necessary - you can use an old T-Shirt or Rag to remove the rough edges of the pipe after cutting it)
    • H. Other tools to get the job done that you might require.
General Instructions
I could bother with how to assemble everything, but I am not going to because every configuration is different. Instead I am going to just describe general dos and don'ts.
  • Use Teflon tape and pipe sealer on top of the Teflon tape for all threaded ends. If you don't, you will have air leaks which really will just ruin the whole assembly as air leaks will kill your water pressure.
  • Use Teflon tape and pipe sealer on the PVC threaded fittings also. It isn't just for the metal threads.
  • Take extra special care when tightening PVC threaded fittings (male end) into metal threaded openings (female end). If you over tighten it, you will crack it and you will want to kill yourself...
  • When cutting your PVC, it is better to go longer, than shorter if you are not sure. You can trim as needed with a hack saw or a PVC pipe cutter.
  • Make sure you buy the right size check valve - if you are decreasing the size of your pipe with a coupler so that your check valve will fit, then you have the wrong size check valve.
  • Keep your pipe sizes consistent - do not decrease or increase sizes unless you absolutely need to. Your system should utilize the same size everywhere.
  • Make 100% sure the check valve is pointing in the correct direction. The angled/beveled end should pointing towards the pump - there are arrows indicating the direction of the flow. You want it to flow into the pump. The check valve prevents back flow so you do not have to prime your pump or the well more than once if everything is done correctly.
  • Make sure to close all valves during operation and cap them off with valve caps to prevent contamination or air from leaking into the line.
  • You can use the gate/ball valve to change zones while the pump is running. To do this, just close the gate valve and open it again. This action will change zones.
  • If when you turn on your pump - no water is flowing - make sure you have the correct cam installed in the indexing valve and that you have connected your zone pipes to the correct zone outlets of the indexing valve. THE ZONE OUTLETS ON THE INDEXING VALVE ARE NOT ARBITRARY THEY ARE FIXED! I made this mistake and I had to hack/retrofit my 2 zone cam to force it to use zones 3 and 4 instead of zones 1 and 2 as the cam and indexer intended. Do not make this mistake!
  • When ready - build a box/home for your pump assembly to keep it out of the sun. The sun (and other weather) will destroy your assembly quickly because plastic does not like heat. I built mine out of 2"x2"x10' pieces of wood for framing and 3/4" pressure treated plywood for the paneling. Make sure to leave your box out in the elements unpainted for about 60-90 days. Then sand, prime and paint it to avoid cracking.
Pictures
This is the most important part - it is the visual aid which I could not find anywhere online. Depicted below is my pump's configuration. These are only the highlights, but I do have more pictures located in my picasa web album. The pictures are large, I did that on purpose for detail.

Plenty of pictures in this album - all large pictures.
Sprinkler System Centrifugal Pump Configuration

System break down

Make sure that check valve is going in the right direction

Pressure gauge with 2 adapters to make it work.

Make shift plugs for the unused zones

Showing my screw up with the indexing
valve configuration and the  zone cams