分享基於EF+WCF的通用三層架構及解析


本項目結合EF 4.3及WCF實現了經典三層架構,各層面向接口,WCF實現SOA,Repository封裝調用,在此基礎上實現了WCFContext,動態服務調用及一個分頁的實例。

1. 項目架構圖:

 

 


2. 項目解決方案:

 

  • 在傳統的三層架構上增加了WcfService(服務端),WcfClientProxy(客戶端服務調用),及WcfExtension(一些擴展)

 


 

3. Wcf Service的實現:

 

  • 工廠實現了RemoteServiceFactory(用於遠程調用)和RefServiceFactory(本地引用調用服務層)生成客戶端代理,都需要實現IServiceFactory的“IService CreateService();”
  • RemoteServiceFactory通過ChannelFactory動態產生客戶端代理類IService,並將此對象進行緩存
  • WCFExtension實現了WCFContext,可傳輸用戶登陸或IP上下文信息,以及攔截方法寫Log的機制,具體可以參考 http://www.cnblogs.com/lovecindywang/archive/2012/03/01/2376144.html


 


3. 數據層Repository的實現:
 
  •  通過用來訪問領域對象的一個類似集合的接口,在領域與數據映射層之間進行協調,將領域模型從客戶代碼和數據映射層之間解耦出來,具體實現代碼:
View Code
 1  public  class DaoBase : IRepository, IDisposable
 2     {
 3          public DbContext context;
 4 
 5          public DaoBase()
 6         {
 7              this.context =  new EasyEF.DAL.DbContext();
 8         }
 9 
10          public T Update<T>(T entity)  where T :  class
11         {
12              var  set = context.Set<T>();
13              set.Attach(entity);
14             context.Entry<T>(entity).State = EntityState.Modified;
15             context.SaveChanges();
16 
17              return entity;
18         }
19 
20          public T Insert<T>(T entity)  where T :  class
21         {
22             context.Set<T>().Add(entity);
23             context.SaveChanges();
24              return entity;
25         }
26 
27          public  void Delete<T>(T entity)  where T :  class
28         {
29             context.Entry<T>(entity).State = EntityState.Deleted;
30             context.SaveChanges();
31         }
32 
33          public T Find<T>( params  object[] keyValues)  where T :  class
34         {
35              return context.Set<T>().Find(keyValues);
36         }
37 
38          public List<T> FindAll<T>(Expression<Func<T,  bool>> conditions =  nullwhere T :  class
39         {
40              if (conditions ==  null)
41                  return context.Set<T>().ToList();
42              else
43                  return context.Set<T>().Where(conditions).ToList();
44         }
45 
46          public PagedList<T> FindAllByPage<T, S>(Expression<Func<T,  bool>> conditions, Expression<Func<T, S>> orderBy,  int pageSize,  int pageIndex)  where T :  class
47         {
48              var queryList = conditions ==  null ? context.Set<T>() : context.Set<T>().Where(conditions)  as IQueryable<T>;
49 
50              return queryList.OrderByDescending(orderBy).ToPagedList(pageIndex, pageSize);
51         }
52 
53          public  void Dispose()
54         {
55              this.context.Dispose();
56         }

 
4. 數據層基於Entity Framwork code First:
  • DBContext
    View Code
     1  public  class DbContext : System.Data.Entity.DbContext
     2     {
     3          public DbContext()
     4             :  base( " MyDbContext ")
     5         {
     6              this.Configuration.ProxyCreationEnabled =  false;
     7         }
     8         
     9          public DbSet<Category> Categories {  getset; }
    10          public DbSet<Product> Products {  getset; }
    11     }
  • Model Mapping
    View Code
     1 [Table( " Product ")]
     2      public  partial  class Product
     3     {
     4          public  int Id {  getset; }
     5 
     6         [StringLength( 50)]
     7         [Required(ErrorMessage =  " 名稱不能為空 ")]
     8          public  string Name {  getset; }
     9 
    10          public  int Size {  getset; }
    11 
    12         [StringLength( 300)]
    13          public  string PhotoUrl {  getset; }
    14 
    15          public DateTime AddTime {  getset; }
    16 
    17          public  int CategoryId {  getset; }
    18          public  virtual Category Category {  getset; }
    19     }

5. 提供了MVC調用服務端分頁的實例:
  • MVC調用Wcf客戶代理請求分頁數據集合
    1  public ActionResult Index( int pageIndex  =  1)
    2         {
    3              var products =  this.Service.GetProducts(PageSize, pageIndex);
    4              return View(products);
    5         }
  • MVC附加用戶Context信息到服務端
    1  protected  override  void OnActionExecuting(ActionExecutingContext filterContext)
    2         {
    3              base.OnActionExecuting(filterContext);
    4             WCFContext.Current.Operater =  new Operater(){Name =  " guozili ",Time = DateTime.Now,IP = Fetch.UserIp,};
    5         }
  • BLL取出Context信息並調用數據層
    1  public PagedList<Product> GetProducts( int pageSize,  int pageIndex,  int categoryId =  0)
    2         {
    3              // Test WCFContext
    4              var context = WCFContext.Current.Operater;
    5              return  this.dao.FindAllByPage<Product,  int>(p => categoryId ==  0 ?  true : p.CategoryId == categoryId, p => p.Id, pageSize, pageIndex);
    6         }
  • DAL調用通用的Repository接口
    1  public PagedList<T> FindAllByPage<T, S>(Expression<Func<T,  bool>> conditions, Expression<Func<T, S>> orderBy,  int pageSize,  int pageIndex)  where T :  class
    2         {
    3              var queryList = conditions ==  null ? context.Set<T>() : context.Set<T>().Where(conditions)  as IQueryable<T>;
    4 
    5              return queryList.OrderByDescending(orderBy).ToPagedList(pageIndex, pageSize);
    6         }

 


6. 最后提供源碼下載
http://files.cnblogs.com/guozili/EasyEF.rar

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM