数据库形式的歧异使大家为各类应用程序编写单独的多寡访问层,数据库方式的距离使大家为各样应用程序编写单独的数量访问层

MVC+EF 驾驭和贯彻仓库储存方式和办事单元格局

原文:Understanding Repository and Unit of Work Pattern and
Implementing Generic Repository in ASP.NET MVC using Entity
Framework

MVC+EF 掌握和兑现仓库储存格局和做事单元方式

原文:Understanding Repository and Unit of Work Pattern and
Implementing Generic Repository in ASP.NET MVC using Entity
Framework

小说介绍

在那篇小说中,大家试着来驾驭Repository(下文简称仓库储存)和Unit of
Work(下文简称职业单元)格局。同时大家采纳ASP.NET MVC和Entity Framework
搭建三个回顾的web应用来兑现通用仓库储存和行事单元形式。

文章介绍

在那篇小说中,大家试着来通晓Repository(下文简称仓库储存)和Unit of
Work(下文简称工作单元)情势。同时大家采纳ASP.NET MVC和Entity Framework
搭建三个简练的web应用来落到实处通用仓库储存和劳作单元方式。

背景

自个儿记得在.NET
一.一的时期,大家不得不费用多量的时刻为每一种应用程序编写数据访问代码。纵然代码的习性差不离一模同样,数据库方式的差别使大家为每一个应用程序编写单独的数额访问层。在新本子的.NET框架中,在我们的应用程序中应用orm(对象-关系映射工具)使我们幸免像在此之前一样编写多量的数据访问层的代码成为大概

由于orm的数码访问操作变得那么轻便间接,导致数据访问逻辑和逻辑谓词(predicates)有望分流在全体应用程序中。例如,每一种调节器都有ObjectContext对象的实例,都能够拓展多少访问。

存款和储蓄形式和行事单位方式使通过O帕JeroM举办数量访问操作更是干净整洁,把富有的数额访问两种在三个岗位,并且使程序维持可测试的力量。让咱们因此在二个总结的MVC应用程序中贯彻仓库储存情势和行事单元来代替枯燥的座谈他们(“Talk
is cheap,show me the code!)

背景

本身记得在.NET
壹.1的时代,我们只可以费用多量的日子为每一种应用程序编写数据访问代码。固然代码的性质大概同样,数据库方式的区别使我们为各样应用程序编写单独的数额访问层。在新本子的.NET框架中,在我们的应用程序中使用orm(对象-关系映射工具)使大家防止像以前一样编写多量的数量访问层的代码成为恐怕

是因为orm的数目访问操作变得那么轻便直接,导致数据访问逻辑和逻辑谓词(predicates)有非常的大可能率分流在一切应用程序中。例如,各种调控器都有ObjectContext对象的实例,都得以举办多少访问。

存款和储蓄格局和行事单位格局使通过OHavalM实行数量访问操作更是干净卫生,把具有的数码访问二种在一个职分,并且使程序维持可测试的技艺。让大家通过在三个大概的MVC应用程序中落到实处仓库储存方式和办事单元来顶替枯燥的斟酌他们(“Talk
is cheap,show me the code!)

创立代码

第3选择vs创设1个MVC web应用程序,然后在Models中增多三个简练的
Books类,大家将对那么些类进行数据库的CRUD操作。(原来的小说使用的DB
First情势搭建实例,鉴于笔者从初始专业接触EF就不曾当真的展开DB
First格局的就学,所以那边使用Code First形式来拓展现身说法)

 [Table("Books")]
    public class Book 
    {
        [Key]
        public int Id { get; set; }

        [Column(TypeName = "varchar")]
        [MaxLength(100)]
        [Display(Name = "封面")]
        public string Cover { get; set; }
        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "书名")]
        public string BookName { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "作者")]
        public string Author { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "译名")]
        public string TranslatedName { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "译者")]
        public string Translator { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "出版社")]
        public string Publisher { get; set; }

        [Display(Name = "字数")]
        public int WordCount { get; set; }

        [Display(Name = "页数")]
        public int Pages { get; set; }

        [Column(TypeName = "varchar")]
        [MaxLength(50)]
        [Display(Name = "ISBN号")]
        public string ISBN { get; set; }

        [Column(TypeName = "float")]
        [Display(Name = "定价")]
        public double Price { get; set; }

        [Column(TypeName = "float")]
        [Display(Name = "售价")]
        public double SalePrice { get; set; }

        [Column(TypeName="date")]
        [Display(Name="出版日期")]
        public DateTime PublicationDate { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(1000)]
        [Display(Name = "内容简介")]
        [DataType(DataType.MultilineText)]
        public string Introduction { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(1000)]
        [Display(Name = "作者简介")]
        [DataType(DataType.MultilineText)]
        public string AboutTheAuthors { get; set; }

        [Column(TypeName = "varchar")]
        [MaxLength(100)]
        [Display(Name = "购买链接")]
        public string Link { get; set; }

下一场就是在程序包管理器调整沈阳输入数据迁移指令来贯彻数据表的开创(在此以前的步调借使还不会的话,提议先去看下MVC基础项目搭建!)1般是逐1实施者如下八个指令就可以,笔者说一般:

PM> Enable-migrations
PM>add-migration createBook
PM> update-database

 

可以用Vs自带的服务器能源管理器张开生成的数据库查看表音信。

开创代码

第3利用vs创立八个MVC web应用程序,然后在Models中加多八个简练的 Books类,我们将对那么些类进行数据库的CRUD操作。(原来的书文使用的DB
First格局搭建实例,鉴于本人从开首专业接触EF就一贯不认真的开始展览DB
First方式的就学,所以那里使用Code First方式来拓突显身说法)

 [Table("Books")]
    public class Book 
    {
        [Key]
        public int Id { get; set; }

        [Column(TypeName = "varchar")]
        [MaxLength(100)]
        [Display(Name = "封面")]
        public string Cover { get; set; }
        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "书名")]
        public string BookName { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "作者")]
        public string Author { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "译名")]
        public string TranslatedName { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "译者")]
        public string Translator { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(200)]
        [Display(Name = "出版社")]
        public string Publisher { get; set; }

        [Display(Name = "字数")]
        public int WordCount { get; set; }

        [Display(Name = "页数")]
        public int Pages { get; set; }

        [Column(TypeName = "varchar")]
        [MaxLength(50)]
        [Display(Name = "ISBN号")]
        public string ISBN { get; set; }

        [Column(TypeName = "float")]
        [Display(Name = "定价")]
        public double Price { get; set; }

        [Column(TypeName = "float")]
        [Display(Name = "售价")]
        public double SalePrice { get; set; }

        [Column(TypeName="date")]
        [Display(Name="出版日期")]
        public DateTime PublicationDate { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(1000)]
        [Display(Name = "内容简介")]
        [DataType(DataType.MultilineText)]
        public string Introduction { get; set; }

        [Column(TypeName = "nvarchar")]
        [MaxLength(1000)]
        [Display(Name = "作者简介")]
        [DataType(DataType.MultilineText)]
        public string AboutTheAuthors { get; set; }

        [Column(TypeName = "varchar")]
        [MaxLength(100)]
        [Display(Name = "购买链接")]
        public string Link { get; set; }

接下来正是在先后包管理器调整埃德蒙顿输入数据迁移指令来兑现数据表的成立(从前的手续假设还不会的话,提议先去看下MVC基础项目搭建!)1般是种种施行者如下几个指令就能够,作者说一般:

PM> Enable-migrations
PM>add-migration createBook
PM> update-database

 

能够用Vs自带的服务器财富管理器展开生成的数据库查看表音讯。

使用MVC Scaffolding

于今我们的预备工作已经变成,能够行使Entity
Framework来拓展支付了,大家利用VS自带的MVC模板创制2个Controller来成功Books
表的CRUD操作。

在消除方案中Controllers文件夹右键,采用增加Controller,在窗口中甄选“包括视图的MVC
x调整器(使用Entity Framework)”

图片 1

public class BooksController : Controller
    {
        private MyDbContext db = new MyDbContext();

        // GET: Books
        public ActionResult Index()
        {
            return View(db.Books.ToList());
        }

        // GET: Books/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: Books/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Books/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                db.Books.Add(book);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: Books/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                db.Entry(book).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: Books/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = db.Books.Find(id);
            db.Books.Remove(book);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }

F5起动调节和测试,大家理应是已经得以对Books实行CRUD操作了

当今从代码和效率的角度来看这么做并未怎么错。但那种方式有两个难点。

  1. 多少方面包车型地铁代码零散分布在应用程序中(Controllers),那将是早先时期程序维护的恐怖的梦
  2. 在调控器(Controller)和动作(Action)内部创设了数码上下文(Context),这使得成效无法通过伪数据实行测试,大家无法印证其结果,除非大家运用测试数据。(应该说是作用不足测试)

Note:要是第一点感到不清楚,那推荐阅读有关在MVC中开始展览测试驱动开拓(Test
Driven Development using
MVC)方面包车型大巴始末。为防卫离题,不再本文中进行钻探。

使用MVC Scaffolding

以往我们的准备干活1度造成,可以使用Entity
Framework来开始展览付出了,大家选取VS自带的MVC模板成立1个Controller来达成Books 表的CRUD操作。

在缓解方案中Controllers文件夹右键,采纳增加Controller,在窗口中挑选“包括视图的MVC
x调控器(使用Entity Framework)”

图片 2

public class BooksController : Controller
    {
        private MyDbContext db = new MyDbContext();

        // GET: Books
        public ActionResult Index()
        {
            return View(db.Books.ToList());
        }

        // GET: Books/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: Books/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Books/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                db.Books.Add(book);
                db.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: Books/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                db.Entry(book).State = EntityState.Modified;
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: Books/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = db.Books.Find(id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = db.Books.Find(id);
            db.Books.Remove(book);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }

F5运转调节和测试,大家应有是现已足以对Books实行CRUD操作了

以往从代码和功效的角度来看这样做并不曾什么错。但那种办法有三个难题。

  1. 多少方面包车型客车代码零散分布在应用程序中(Controllers),那将是中期程序维护的惊恐不已的梦
  2. 在调控器(Controller)和动作(Action)内部创建了多少上下文(Context),那使得成效不能通过伪数据进行测试,大家无能为力证实其结果,除非大家利用测试数据。(应该算得功效不可测试)

Note:假如第3点感到不清晰,那推荐阅读有关在MVC中举行测试驱动开拓(Test
Driven Development using
MVC)方面包车型地铁始末。为严防离题,不再本文中举行探究。

完结仓库储存方式

今昔,大家来缓解地点的主题材料。大家得以经过把富有包蕴数据访问逻辑的代码放到一齐来缓解那一个难点。所以让大家定义3个包蕴全数对
Books 表的数量访问逻辑的类

而是在创造这几个类在此以前,大家也顺便考虑下第四个难题。如果大家创造二个简练的定义了拜访Books表的预约的接口然后用刚才提到的类完毕接口,我们会赢得多个益处,大家能够运用另一个类伪造数据来兑现接口。那样,就可以保证Controller是可测试的。(原来的著作很辛勤,正是表述这一个意思)

之所以,我们先定义对 Books 举行数量访问的约定。

    public interface IRepository<T> where T:class
    {
        IEnumerable<T> GetAll(Func<T, bool> predicate = null);
        T Get(Func<T, bool> predicate);
        void Add(T entity);
        void Update(T entity);
        void Delete(T entity);
    }

上面包车型地铁类富含了对 Books 表CRUD操作接口的兑现

 public class BooksRepository:IRepository<Book>
    {
        private MyDbContext dbContext = new MyDbContext();

        public IEnumerable<Book> GetAll(Func<Book, bool> predicate = null)
        {
            if(predicate!=null)
            {
                return dbContext.Books.Where(predicate);
            }
            return dbContext.Books;
        }

        public Book Get(Func<Book, bool> predicate)
        {
            return dbContext.Books.First(predicate);
        }

        public void Add(Book entity)
        {
            dbContext.Books.Add(entity);
        }

        public void Update(Book entity)
        {
            dbContext.Entry(entity).State = EntityState.Modified;
        }

        public void Delete(Book entity)
        {
            dbContext.Books.Remove(entity);
        }
        internal void SaveChanges()
        {
            dbContext.SaveChanges();
        }
    }

现今,我们创制另八个饱含对 Books
表实行CRUD操作的Controller,命名称叫BooksRepoController

public class BooksRepoController : Controller
    {
        private BooksRepository repo = new BooksRepository();

        // GET: Books1
        public ActionResult Index()
        {
            return View(repo.GetAll().ToList());
        }

        // GET: Books1/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = repo.Get(t=>t.Id==id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: Books1/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Books1/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                repo.Add(book);
                repo.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: Books1/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = repo.Get(t => t.Id == id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books1/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                repo.Update(book);
                repo.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: Books1/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = repo.Get(t => t.Id == id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books1/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = repo.Get(t => t.Id == id);
            repo.Delete(book);

            repo.SaveChanges();
            return RedirectToAction("Index");
        }


    }

今昔那种方法的补益是,笔者的OPAJEROM的多少访问代码不是分散在调控器。它被打包在一个Repository类里面。

完成仓库储存格局

现行反革命,大家来化解地方的难点。我们得以经过把装有包蕴数据访问逻辑的代码放到一同来缓解那些主题材料。所以让我们定义一个饱含全数对 Books 表的数码访问逻辑的类

不过在创制那一个类以前,我们也顺便思考下第四个难点。倘若大家制造一个轻松的定义了走访Books表的约定的接口然后用刚才提到的类完成接口,大家会获得1个利润,大家得以应用另三个类伪造数据来落实接口。那样,就能够保持Controller是可测试的。(原来的小说很辛劳,正是抒发那几个意思)

为此,大家先定义对 Books 进行多少访问的预约。

    public interface IRepository<T> where T:class
    {
        IEnumerable<T> GetAll(Func<T, bool> predicate = null);
        T Get(Func<T, bool> predicate);
        void Add(T entity);
        void Update(T entity);
        void Delete(T entity);
    }

下边包车型地铁类富含了对 Books 表CRUD操作接口的兑现

 public class BooksRepository:IRepository<Book>
    {
        private MyDbContext dbContext = new MyDbContext();

        public IEnumerable<Book> GetAll(Func<Book, bool> predicate = null)
        {
            if(predicate!=null)
            {
                return dbContext.Books.Where(predicate);
            }
            return dbContext.Books;
        }

        public Book Get(Func<Book, bool> predicate)
        {
            return dbContext.Books.First(predicate);
        }

        public void Add(Book entity)
        {
            dbContext.Books.Add(entity);
        }

        public void Update(Book entity)
        {
            dbContext.Entry(entity).State = EntityState.Modified;
        }

        public void Delete(Book entity)
        {
            dbContext.Books.Remove(entity);
        }
        internal void SaveChanges()
        {
            dbContext.SaveChanges();
        }
    }

如今,我们创立另3个分包对 Books 表实行CRUD操作的Controller,命名称为BooksRepoController

public class BooksRepoController : Controller
    {
        private BooksRepository repo = new BooksRepository();

        // GET: Books1
        public ActionResult Index()
        {
            return View(repo.GetAll().ToList());
        }

        // GET: Books1/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = repo.Get(t=>t.Id==id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: Books1/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Books1/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                repo.Add(book);
                repo.SaveChanges();

                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: Books1/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = repo.Get(t => t.Id == id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books1/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                repo.Update(book);
                repo.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: Books1/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = repo.Get(t => t.Id == id);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: Books1/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = repo.Get(t => t.Id == id);
            repo.Delete(book);

            repo.SaveChanges();
            return RedirectToAction("Index");
        }


    }

未来那种艺术的益处是,小编的O奥迪Q三M的数量访问代码不是分散在调节器。它被装进在二个Repository类里面。

怎么处理三个Repository库?

上边想象下如下场景,大家数据库中有多少个表,那样大家要求为每一种表创制1个Reporsitory类。(繁多双重工作的说,其实那不成难题)

题目是有关 数据上下文(DbContext)
对象的。假设我们成立多个Repository类,是或不是每多个都单身的涵盖2个数据上下文对象?我们驾驭并且选择八个 数据上下文会设万分,那大家该怎么处理各类Repository都持有和谐的数额上下文
对象的标题?

来缓解这一个难题吗。为何每一种Repository要具备几个数额上下文的实例呢?为啥不在1些地点创立二个它的实例,然后在repository被实例化的时候作为参数传递进去吧。现在以此新的类被取名称为UnitOfWork
,此类将负担创制数量上下文实例并移交到调节器的有所repository实例。

怎样处理八个Repository库?

下边想象下如下场景,大家数据库中有多个表,那样大家要求为各种表创制一个Reporsitory类。(好些个再度职业的说,其实那寻常)

标题是关于 数据上下文(DbContext) 对象的。如若大家创立多少个Repository类,是否每三个都单身的蕴藏1个 数据上下文对象?大家领略并且使用多少个 数据上下文 会设有毛病,这大家该怎么处理每一种Repository都独具和谐的数量上下文 对象的难题?

来化解那个主题材料啊。为啥每种Repository要享有二个数码上下文的实例呢?为啥不在1些地点创立2个它的实例,然后在repository被实例化的时候作为参数字传送递进去吧。今后这些新的类被取名称叫 UnitOfWork ,此类将负责创立数量上下文实例并移交到控制器的具有repository实例。

完毕工作单元

故此,大家在单身创立三个选择 UnitOfWork
的Repository类,数据上下文对象将从外边传递给它之所以,让大家创设五个单身的仓库储存库将运用通过UnitOfWork类和指标上下文将被传送到此类以外。

    public class BooksRepositoryWithUow : IRepository<Book>
    {
        private MyDbContext dbContext = null;

        public BooksRepositoryWithUow(MyDbContext _dbContext)
        {
            dbContext = _dbContext;
        }
        public IEnumerable<Book> GetAll(Func<Book, bool> predicate = null)
        {
            if (predicate != null)
            {
                return dbContext.Books.Where(predicate);
            }
            return dbContext.Books;
        }
        public Book Get(Func<Book, bool> predicate)
        {
            return dbContext.Books.FirstOrDefault(predicate);
        }

        public void Add(Book entity)
        {
            dbContext.Books.Add(entity);
        }

        public void Update(Book entity)
        {
            dbContext.Entry(entity).State = EntityState.Modified;
        }

        public void Delete(Book entity)
        {
            dbContext.Books.Remove(entity);
        }

    }

到现在这一个Repository类将从类的外界获得DbContext对象(每当它被创制时).

以后,假使大家创设七个仓库储存类,我们在仓库储存类实例化的时候获得 ObjectContext
对象。让大家来看下 UnitOfWork 怎么样创造仓库储存类并且传递到Controller中的。

public class UnitOfWork : IDisposable
    {
        private MyDbContext dbContext = null;
        public UnitOfWork()
        {
            dbContext = new MyDbContext();
        }

        IRepository<Book> bookReporsitory = null;

        public IRepository<Book> BookRepository
        {
            get
            {
                if (bookReporsitory == null)
                {
                    bookReporsitory = new BooksRepositoryWithUow(dbContext);
                }
                return bookReporsitory;
            }
        }

        public void SaveChanges()
        {
            dbContext.SaveChanges();
        }

        private bool disposed = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    dbContext.Dispose();
                }
                this.disposed = true;
            }
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

现行反革命我们在创立三个Controller,命名字为 BooksUowController 将因而调用
职业单元类来兑现 Book 表的CRUD操作

public class BooksUowController : Controller
    {
        private UnitOfWork uow = null;
        //private MyDbContext db = new MyDbContext();

        public BooksUowController() {
            uow = new UnitOfWork();
        }
        public BooksUowController(UnitOfWork _uow)
        {
            this.uow = _uow;
        }

        // GET: BookUow
        public ActionResult Index()
        {
            return View(uow.BookRepository.GetAll().ToList());
        }

        // GET: BookUow/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.BookRepository.Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: BookUow/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: BookUow/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.BookRepository.Add(book);
                uow.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: BookUow/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.BookRepository.Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: BookUow/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.BookRepository.Update(book);
                uow.SaveChanges();

                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: BookUow/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.BookRepository.Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: BookUow/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = uow.BookRepository.Get(b => b.Id == id);
            uow.BookRepository.Delete(book);
            uow.SaveChanges();
            return RedirectToAction("Index");
        }

    }

当今,Controller通过暗中同意的构造函数完成了可测试技巧。例如,测试项目可以为UnitOfWork
传入虚拟的测试数据来取代真实数据。一样数量访问的代码也被集中到三个地方。

落到实处工作单元

于是,大家在单独成立3个利用 UnitOfWork 的Repository类,数据上下文对象将从外侧传递给它之所以,让大家创制三个独自的贮存库将利用通过UnitOfWork类和对象上下文将被传送到此类以外。

    public class BooksRepositoryWithUow : IRepository<Book>
    {
        private MyDbContext dbContext = null;

        public BooksRepositoryWithUow(MyDbContext _dbContext)
        {
            dbContext = _dbContext;
        }
        public IEnumerable<Book> GetAll(Func<Book, bool> predicate = null)
        {
            if (predicate != null)
            {
                return dbContext.Books.Where(predicate);
            }
            return dbContext.Books;
        }
        public Book Get(Func<Book, bool> predicate)
        {
            return dbContext.Books.FirstOrDefault(predicate);
        }

        public void Add(Book entity)
        {
            dbContext.Books.Add(entity);
        }

        public void Update(Book entity)
        {
            dbContext.Entry(entity).State = EntityState.Modified;
        }

        public void Delete(Book entity)
        {
            dbContext.Books.Remove(entity);
        }

    }

近期以此Repository类将从类的外围获得DbContext对象(每当它被创设时).

前天,倘诺我们成立五个仓库储存类,大家在储存类实例化的时候得到 ObjectContext 对象。让我们来看下 UnitOfWork 怎么样创制仓库储存类并且传递到Controller中的。

public class UnitOfWork : IDisposable
    {
        private MyDbContext dbContext = null;
        public UnitOfWork()
        {
            dbContext = new MyDbContext();
        }

        IRepository<Book> bookReporsitory = null;

        public IRepository<Book> BookRepository
        {
            get
            {
                if (bookReporsitory == null)
                {
                    bookReporsitory = new BooksRepositoryWithUow(dbContext);
                }
                return bookReporsitory;
            }
        }

        public void SaveChanges()
        {
            dbContext.SaveChanges();
        }

        private bool disposed = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    dbContext.Dispose();
                }
                this.disposed = true;
            }
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

前几天我们在创造贰个Controller,命名字为 BooksUowController 将通过调用 工作单元类来兑现 Book 表的CRUD操作

public class BooksUowController : Controller
    {
        private UnitOfWork uow = null;
        //private MyDbContext db = new MyDbContext();

        public BooksUowController() {
            uow = new UnitOfWork();
        }
        public BooksUowController(UnitOfWork _uow)
        {
            this.uow = _uow;
        }

        // GET: BookUow
        public ActionResult Index()
        {
            return View(uow.BookRepository.GetAll().ToList());
        }

        // GET: BookUow/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.BookRepository.Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: BookUow/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: BookUow/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.BookRepository.Add(book);
                uow.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: BookUow/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.BookRepository.Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: BookUow/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.BookRepository.Update(book);
                uow.SaveChanges();

                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: BookUow/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.BookRepository.Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: BookUow/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = uow.BookRepository.Get(b => b.Id == id);
            uow.BookRepository.Delete(book);
            uow.SaveChanges();
            return RedirectToAction("Index");
        }

    }

现行反革命,Controller通过私下认可的构造函数完成了可测试技术。例如,测试项目可感觉 UnitOfWork 传入虚拟的测试数据来代替真实数据。一样数目访问的代码也被集中到八个地方。

通用仓库储存和办事单元

最近大家曾经创设了仓库储存类和
工作单元类。将来的问题是只要数据库包蕴众多表,那样咱们供给创制很多储存类,然后咱们的干活单元类须求为各样仓库储存类创造四个走访属性

比方为具有的Mode类创制三个通用的储存类和
职业单元类岂不是越来越好,所以大家继续来贯彻八个通用的积存类。

 public class GenericRepository<T> : IRepository<T> where T : class
    {
        private MyDbContext dbContext = null;
        IDbSet<T> _objectSet;

        public GenericRepository(MyDbContext _dbContext)
        {
            dbContext = _dbContext;
            _objectSet = dbContext.Set<T>();
        }

        public IEnumerable<T> GetAll(Expression< Func<T, bool>> predicate = null)
        {
            if (predicate != null)
            {
                return _objectSet.Where(predicate);
            }
            return _objectSet.AsEnumerable();
        }
        public T Get(Expression<Func<T, bool>> predicate)
        {
            return _objectSet.First(predicate);
        }
        public void Add(T entity)
        {
            _objectSet.Add(entity);
        }

        public void Update(T entity)
        {
            _objectSet.Attach(entity);
        }

        public void Delete(T entity)
        {
            _objectSet.Remove(entity);
        }

        public IEnumerable<T> GetAll(Func<T, bool> predicate = null)
        {
            if (predicate != null)
            {
                return _objectSet.Where(predicate);
            }
            return _objectSet.AsEnumerable();
        }

        public T Get(Func<T, bool> predicate)
        {
            return _objectSet.First(predicate);
        }
    }

UPDATE: 发现1个很有用的褒贬,作者感觉应当投身小说中享用一下

在.NET中,对‘Where’至少有五个重写方法:

public static IQueryable Where(this IQueryable source, Expression> predicate);
public static IEnumerable Where(this IEnumerable source, Func predicate);

近年来大家正在利用的是

Func<T, bool>

今日的查询将会接纳’IEnumerable’版本,在演示中,首先从数据库中抽出整个表的记录,然后再实施过滤条件得到最终的结果。想要申明那一点,只要去探视生成的sql语句,它是不带有Where字句的。

若要化解这些主题材料,大家必要修改’Func’ to ‘Expression Func’.

Expression<Func<T, bool>> predicate 

今昔 ‘Where’方法运用的就是 ‘IQueryable’版本了。

Note: 由此看来,使用 Expression Func 比起采用 Func是越来越好的主意.

今昔选取通用的仓库储存类,大家须要创立四个对应的做事单元类。这一个工作单元类将检查仓库储存类是或不是已经创办,纵然存在将回来贰个实例,不然将创建1个新的实例。

 public class GenericUnitOfWork:IDisposable
    {
        private MyDbContext dbContext=null;

        public GenericUnitOfWork()
        {
            dbContext = new MyDbContext();
        }
        public Dictionary<Type, object> repositories = new Dictionary<Type, object>();

        public IRepository<T> Repository<T>() where T : class
        {
            if (repositories.Keys.Contains(typeof(T)) == true)
            {
                return repositories[typeof(T)] as IRepository<T>;
            }
            IRepository<T> repo=new GenericRepository<T>(dbContext);
            repositories.Add(typeof(T), repo);
            return repo;
        }
        public void SaveChanges()
        {
            dbContext.SaveChanges();
        }

        private bool disposed = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    dbContext.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

然后,大家在开立一个使用通用工作单元类 GenericUnitOfWork
的Controller,命名称为GenericContactsController ,完结对 Book
表的CRUD操作。

 public class GenericBooksController : Controller
    {
        private GenericUnitOfWork uow = null;
        //private MyDbContext db = new MyDbContext();

        public GenericBooksController()
        {
            uow = new GenericUnitOfWork();
        }

        public GenericBooksController(GenericUnitOfWork uow)
        {
            this.uow = uow;
        }

        // GET: GenericBooks
        public ActionResult Index()
        {
            return View(uow.Repository<Book>().GetAll().ToList());
        }

        // GET: GenericBooks/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.Repository<Book>().Get(b=>b.Id==id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: GenericBooks/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: GenericBooks/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.Repository<Book>().Add(book);
                uow.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: GenericBooks/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.Repository<Book>().Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: GenericBooks/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.Repository<Book>().Update(book);
                uow.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: GenericBooks/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.Repository<Book>().Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: GenericBooks/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = uow.Repository<Book>().Get(b => b.Id == id);
            uow.Repository<Book>().Delete(book);
            uow.SaveChanges();
            return RedirectToAction("Index");
        }

    }

明日,大家早已在消除方案中具体了三个通用的贮存类和办事单元类

通用仓库储存和工作单元

近期大家已经创造了储存类和 职业单元类。今后的标题是即使数据库包含众多表,那样我们要求成立好多存款和储蓄类,然后大家的工作单元类须求为每一个仓库储存类创立二个拜访属性

设若为富有的Mode类成立叁个通用的储存类和 职业单元类岂不是更加好,所以大家一而再来贯彻三个通用的积存类。

 public class GenericRepository<T> : IRepository<T> where T : class
    {
        private MyDbContext dbContext = null;
        IDbSet<T> _objectSet;

        public GenericRepository(MyDbContext _dbContext)
        {
            dbContext = _dbContext;
            _objectSet = dbContext.Set<T>();
        }

        public IEnumerable<T> GetAll(Expression< Func<T, bool>> predicate = null)
        {
            if (predicate != null)
            {
                return _objectSet.Where(predicate);
            }
            return _objectSet.AsEnumerable();
        }
        public T Get(Expression<Func<T, bool>> predicate)
        {
            return _objectSet.First(predicate);
        }
        public void Add(T entity)
        {
            _objectSet.Add(entity);
        }

        public void Update(T entity)
        {
            _objectSet.Attach(entity);
        }

        public void Delete(T entity)
        {
            _objectSet.Remove(entity);
        }

        public IEnumerable<T> GetAll(Func<T, bool> predicate = null)
        {
            if (predicate != null)
            {
                return _objectSet.Where(predicate);
            }
            return _objectSet.AsEnumerable();
        }

        public T Get(Func<T, bool> predicate)
        {
            return _objectSet.First(predicate);
        }
    }

UPDATE: 发现3个很有用的评论,笔者觉着应当放在小说中享用一下

在.NET中,对‘Where’至少有多少个重写方法:

public static IQueryable Where(this IQueryable source, Expression> predicate);
public static IEnumerable Where(this IEnumerable source, Func predicate);

最近我们正在选取的是

Func<T, bool>

今日的查询将会动用’IEnumerable’版本,在演示中,首先从数据库中抽出整个表的记录,然后再举办过滤条件获得最终的结果。想要申明这点,只要去探视生成的sql语句,它是不分包Where字句的。

若要解决那个主题材料,大家必要修改’Func’ to
‘Expression Func’.

Expression<Func<T, bool>> predicate 

以后 ‘Where’方法应用的正是 ‘IQueryable’版本了。

Note: 因此看来,使用 Expression
Func 比起利用 Func是更加好的主意.

现行反革命利用通用的囤积类,我们须要创建二个一见依旧的办事单元类。这么些职业单元类将检查仓库储存类是不是已经创办,假使存在将回来一个实例,不然将创立三个新的实例。

 public class GenericUnitOfWork:IDisposable
    {
        private MyDbContext dbContext=null;

        public GenericUnitOfWork()
        {
            dbContext = new MyDbContext();
        }
        public Dictionary<Type, object> repositories = new Dictionary<Type, object>();

        public IRepository<T> Repository<T>() where T : class
        {
            if (repositories.Keys.Contains(typeof(T)) == true)
            {
                return repositories[typeof(T)] as IRepository<T>;
            }
            IRepository<T> repo=new GenericRepository<T>(dbContext);
            repositories.Add(typeof(T), repo);
            return repo;
        }
        public void SaveChanges()
        {
            dbContext.SaveChanges();
        }

        private bool disposed = false;
        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    dbContext.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }

下一场,大家在开创1个选拔通用工作单元类 GenericUnitOfWork 的Controller,命名叫GenericContactsController ,实现对 Book 表的CRUD操作。

 public class GenericBooksController : Controller
    {
        private GenericUnitOfWork uow = null;
        //private MyDbContext db = new MyDbContext();

        public GenericBooksController()
        {
            uow = new GenericUnitOfWork();
        }

        public GenericBooksController(GenericUnitOfWork uow)
        {
            this.uow = uow;
        }

        // GET: GenericBooks
        public ActionResult Index()
        {
            return View(uow.Repository<Book>().GetAll().ToList());
        }

        // GET: GenericBooks/Details/5
        public ActionResult Details(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.Repository<Book>().Get(b=>b.Id==id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // GET: GenericBooks/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: GenericBooks/Create
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.Repository<Book>().Add(book);
                uow.SaveChanges();
                return RedirectToAction("Index");
            }

            return View(book);
        }

        // GET: GenericBooks/Edit/5
        public ActionResult Edit(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.Repository<Book>().Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: GenericBooks/Edit/5
        // 为了防止“过多发布”攻击,请启用要绑定到的特定属性,有关 
        // 详细信息,请参阅 http://go.microsoft.com/fwlink/?LinkId=317598。
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Edit([Bind(Include = "Id,Cover,BookName,Author,TranslatedName,Translator,Publisher,WordCount,Pages,ISBN,Price,Introduction,AboutTheAuthors,Link")] Book book)
        {
            if (ModelState.IsValid)
            {
                uow.Repository<Book>().Update(book);
                uow.SaveChanges();
                return RedirectToAction("Index");
            }
            return View(book);
        }

        // GET: GenericBooks/Delete/5
        public ActionResult Delete(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }
            Book book = uow.Repository<Book>().Get(b => b.Id == id.Value);
            if (book == null)
            {
                return HttpNotFound();
            }
            return View(book);
        }

        // POST: GenericBooks/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public ActionResult DeleteConfirmed(int id)
        {
            Book book = uow.Repository<Book>().Get(b => b.Id == id);
            uow.Repository<Book>().Delete(book);
            uow.SaveChanges();
            return RedirectToAction("Index");
        }

    }

于今,大家早就在消除方案中实际了多个通用的囤积类和行事单元类

要点总括

在这篇小说中,我们理解了蕴藏情势和事业单元形式。大家也在ASP.NET
MVC应用中应用Entity
Framework完成了简便的存款和储蓄格局和行事单元格局。然后大家创设了3个通用的储存类和办事单元类来防止在一大堆仓库储存类中编辑重复的代码。笔者愿意您在那篇作品中能有所收获

要点计算

在那篇小说中,大家理解了储存格局和工作单元方式。大家也在ASP.NET
MVC应用中应用Entity
Framework达成了简短的储存方式和行事单元情势。然后大家成立了三个通用的积存类和劳作单元类来制止在一大堆仓库储存类中编辑重复的代码。小编期待您在那篇文章中能有所收获

History

07 May 2014: First version

History

07 May 2014: First version

License

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

License

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

译注

原版的书文选择objectContext,使用EF图形化建立模型编写的演示代码,译者修改code
first格局

译注

初稿采纳objectContext,使用EF图形化建立模型编写的言传身教代码,译者修改code
first格局

参考

https://msdn.microsoft.com/en-us/data/jj592676.aspx

https://msdn.microsoft.com/en-us/library/system.data.entity.dbset(v=vs.113).aspx

http://stackoverflow.com/questions/8947427/differences-between-createobjectsett-sett-and-createqueryt

参考

https://msdn.microsoft.com/en-us/data/jj592676.aspx

https://msdn.microsoft.com/en-us/library/system.data.entity.dbset(v=vs.113).aspx

http://stackoverflow.com/questions/8947427/differences-between-createobjectsett-sett-and-createqueryt

转载自:http://www.cnblogs.com/wit13142/p/5432147.html

相关文章