Given the following model

public class Context : DbContext
{
    public virtual DbSet<Product> Products { get; set; }
    public virtual DbSet<ProductCategory> Categories { get; set; }
 
    public Context()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<Context>());
    }
}
 
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ProductCategoryId { get; set; }
    public virtual ProductCategory ProductCategory { get; set; }
}
 
public class ProductCategory
{
    public int Id { get; set; }
    public string Name { get; set; }
}

In order to manipulate products, we can create a Repository like this :

using(Context ctx = new Context())
{
    DbContextAdapter adapter = new DbContextAdapter(ctx);
    IRepository<Product> productRepo = new Repository<Product>(adp);
}

Let's query the database to fetch all products :

IEnumerable<Product> lst = productRepo.GetAll();

Now, let's bring back the first item whose name begins with "Bike"

Product prod = productRepo.First(p => p.Name.StartsWith("Bike"));

Using the Single method has the same effect (returns only one element), but throws an exception if multiple items meet the criteria.

productRepo.Single(p => p.Name.StartsWith("Roc"))

Find method, filters the resultset based on several criteria :

IEnumerable<Product> lst = productRepo.Find(
                p => p.Id < 100 && p.Name.Contains("o") && p.Name.Length < 20);

All these methods accept an optional set of navigation links between entities materializing joins that will be performed when querying.

productRepo.First(p => p.ProductCategoryId != null , p => p.ProductCategory);

The above syntax loads the product and its associated category in a single SQL query; This approach avoids the N+1 Selects problem, that might appears when using lazy loading.

Now, when you need to "write" to your db you'll need the Unit of work pattern.

using(Context ctx = new Context())
{
   DbContextAdapter adapter = new DbContextAdapter(ctx);
   IRepository<Product> productRepo = new Repository<Product>(adp);
   IUnitOfWork unitOfWork = new UnitOfWork(adp);
   Product p = new Product{Name = "Skateboard"};
   productRepo.Insert(p);
   unitOfWork.Commit();
}

As you can see the update and deletion are as simple as that:

Product p = productRepo.First(c => c.Name == "Bike");
p.Name = "New bike";
productRepo.Update(p);
 
Product delete = productRepo.First(p => p.Name.StartsWith("To be"));
productRepo.Delete(delete);
 
unitOfWork.Commit();

Last edited Oct 10, 2011 at 2:38 PM by Fab_Michellonet, version 3

Comments

TURNSKIN Jul 2, 2013 at 1:08 PM 
maybe UOW (UnitOfWork)?

TURNSKIN Jul 2, 2013 at 1:08 PM 
what is UOF in title?

cbordeman May 28, 2012 at 4:12 PM 
So how do you mock this? Do you have to mock the adapter? Please give a much more in-depth answer. Thanks.