Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: MVC EF
Hi,
 
For all my applications (ASP.NET MVC3, EF Code First), I have this general pattern that i'm using:
 
Entity:
 
public class Product 
    { 
        public int ProductID { get; set; } 
 
        public string Name { get; set; } 
 
        public string Category { get; set; } 
 
        public decimal Price { get; set; } 
    }
 
EFDbContext:
 
public class EFDbContext : DbContext 
    { 
        public DbSet<Product> Products { get; set; } 
 
        protected override void OnModelCreating(DbModelBuilder modelBuilder) 
        { 
            // Product 
            modelBuilder.Entity<Product>() 
                .HasKey(p => p.ProductID) 
                .Property(p => p.ProductID)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 
 
      
        } 
    }
 
I have a Generic Repository, which will be used by my Unit Of Work class, as below:
 
public class UnitOfWork : IUnitOfWork, IDisposable 
    { 
        private readonly EFDbContext context; 
        private IGenericRepository<Product> _productRepository; 
 
        
        public UnitOfWork() 
        { 
            context = new EFDbContext(); 
        } 
        
        public EFDbContext Context 
        { 
            get 
            { 
                return context; 
            } 
        } 
 
        public IGenericRepository<Product> ProductRepository 
        { 
            get 
            { 
                if (_productRepository == null) 
                { 
                    _productRepository = new 
                                         GenericRepository<Product>(context); 
                } 
                return _productRepository; 
            } 
        } 
 
       // save() 
       // Dispose() & so on.. left out
 
I have a Service Layer, which as it should, models business logic. This layer, uses Unit Of Work, as below:
 
public class ProductService : IProductService 
    { 
        private IUnitOfWork unitOfWork; 
 
        public ProductService(IUnitOfWork unitOfWorkParam) 
        { 
            unitOfWork = unitOfWorkParam; 
        } 
 
        public void AddProduct(Product product) 
        { 
            unitOfWork.ProductRepository.Insert(product); 
            unitOfWork.Save(); 
        } 
        // other services for business logic.. 
    }
 
Now, my UI project (ASP.NET MVC3), uses the service layer as below
 
public class HomeController : Controller 
    { 
        private IProductService productService; 
 
        public HomeController(IProductService productServiceParam) 
        { 
            productService = productServiceParam; 
        } 
 
        public ActionResult Products() 
        { 
            // User productService.GetProducts and so on 
        } 
    }
 
Thus the whole setup of the Projects to summazie would be:

Controller --> Service Layer --> UnitOfWork (which contains context, repositories)
--> DB

Now, my question is, the EFDbContext is contained in UnitOfWork, and thus, in this class, we can use queries such as:
 
using (var context = new EFDbContext()) 
{ 
    // use context.Entry<> 
    // use context.Find<> 
    // use context.Attach<> 
    // and other useful functions 
}
 
but, how can i get this functionality migrated to my Service Layer, which uses UnitOfWork.Repositories ?

Have i missed something in design?

It would be great to have the Service Layer capable somehow of using the bare context object, where in we can use useful extension methods such as context.Entry<> ..

Can anyone please help me with this?

thanks.
Posted 4-Aug-12 4:50am
Comments
robroysd at 5-Aug-12 18:58pm
   
FYI, for my own reference, and for anyone interested, i had posted the same issue on forums.asp.net, here's the link
 
http://forums.asp.net/t/1830559.aspx/1?EF+Code+First+Using+DbContext+in+Service+Layer+Help+Needed

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

This looks complex. Why don't you use annotations on your class to define keys, etc ? For example, [Table("Product")] above the class and [Key] above the ProductId.
 
In my code, the DbContext has a private constructor, and a public static instance property, which returns the same instance across requests for the same session ( it uses the session key to do this ). I can access my DBContext from anywhere in my project, but I don't break it up in to dlls, so perhaps your issue is one of what dlls are consumed where ?
  Permalink  
Comments
robroysd at 4-Aug-12 18:13pm
   
I can use data annotations, but i use Fluent API so as to have all relationship maps at one place.
For example:
// Product:
// define product properties such as <Product>().has key etc etc
// define relations such as <Product>().HasMany(SomeList).WithRequired()..
 
This way, i can have everything in one place, i.e. the modelBuilder object.
 
I will look into the DbContext --> public static instance. Thanks.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 505
1 Maciej Los 309
2 BillWoodruff 174
3 /\jmot 160
4 Suraj Sahoo | Coding Passion 160
0 OriginalGriff 8,654
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,639
3 Maciej Los 5,229
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web04 | 2.8.1411023.1 | Last Updated 4 Aug 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100