Entity Fr“.NET技术”amework 4.1 Code First 学习之路(二)
2011-10-13 19:27
531 查看
写系列的上一篇已经是很久之前的事儿了= =在此期间,EF 4.1的RTW都已经出来了,NH 3.2的Alpha已经2了。。。其实不是我懒,工作中也在一直使用EF 4.1。主要是上次承诺过的一个Update功能搞不定= =
总之这一次的目标是:
实现一个完整的IRepository(添加增删改能力)
领域对象的继承
事物
首先来看IRepository
我的接口如下:
[/code]
应该算是一个最基本的仓储接口了。
其中前几个接口都是很好实现的,上次提及的DbSet对象提供了相应的接口,直接调用即可,代码是类似这样的。
[/code]
很明显,在执行Edit这个Action之前,DbSet没有加载过,因为MVC帮我们保证了DbContext实例是request结束就被销毁的。
也就是说,结论是使用这种Update实现方式对context的生命周期是有要求的.当然我的例子中context的生命周期也是per-request的所以没关系。
那么如果我们想使用其他的context生命周期管理方式呢?比如希望整个application只有一个context实例?
让我们来给出另一种实现
回过头来想一想在实现Update这个方法的时候我们最初遇到的问题:entity不是从context中加载的而是直接new出来的。
那么我们手动的来加载一次就好了么,代码类似于这样:
[/code]
当然这个实现也有不好的地方例如说当domain里有一些跟ORM没关系的property时也会被EmitMapper改写掉。
下一个议题是领域对象的继承
让领域对象实现继承的好处是不言而喻的,可以使用到多态等OO带来的好处。相对的就对ORM提出了更高的要求。
我们知道映射对象树到数据库有三种经典的实现方式:Table Per Type、Table Per Hierarchy和Table Per Concrete class,这次我们来实践最简单的一种:Table Per Hierarchy。
回想我们上一次的类:
[/code]
在EF Code First中这种单表继承的映射关系是这样来写的:
另外两种方式的实现也不复杂,可以参考这里。这个实例还是CTP5的API,跟4.1最终版有些区别不过应该影响不大。
今天最后的议题是事物
可以用TransactionScope来管理,虽然看起来有些浪费,毕竟例子中不涉及Transaction传播,连DbContext都只有一个实例。代码如下:
Spring实际上也可以用AOP的方式管理TransactionScope。不过我倾向于手动管理Transaction。
代码下载
本次的代码请参考这个changeset
今天就到这里-v-
总之这一次的目标是:
实现一个完整的IRepository(添加增删改能力)
领域对象的继承
事物
首先来看IRepository
我的接口如下:
[code] [code]public interface IRepository<TEntity> where TEntity : IEntity { IEnumerable<TEntity> FindAll(); TEntity FindById(int id); void Add(TEntity entity); void Delete(TEntity entity); void Update(TEntity entity); }
[/code]
应该算是一个最基本的仓储接口了。
其中前几个接口都是很好实现的,上次提及的DbSet对象提供了相应的接口,直接调用即可,代码是类似这样的。
[code]public class BlogController : Controller { BlogContext db = new BlogContext(); //... [HttpPost] public ActionResult Edit(int id, Blog blog) { try { db.Entry(blog).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } catch { return View(); } } }
[/code]
很明显,在执行Edit这个Action之前,DbSet没有加载过,因为MVC帮我们保证了DbContext实例是request结束就被销毁的。
也就是说,结论是使用这种Update实现方式对context的生命周期是有要求的.当然我的例子中context的生命周期也是per-request的所以没关系。
那么如果我们想使用其他的context生命周期管理方式呢?比如希望整个application只有一个context实例?
让我们来给出另一种实现
回过头来想一想在实现Update这个方法的时候我们最初遇到的问题:entity不是从context中加载的而是直接new出来的。
那么我们手动的来加载一次就好了么,代码类似于这样:
[code]public void上海企业网站制作or: #000000;"> Update(TEntity entity) { var entry = m_dbContext.Entry(entity); if (entry.State == EntityState.Detached) { var entityToUpdate = FindById(entity.Id); EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<TEntity, TEntity>().Map(entity, entityToUpdate); } m_dbContext.SaveChanges(); }
[/code]
当然这个实现也有不好的地方例如说当domain里有一些跟ORM没关系的property时也会被EmitMapper改写掉。
下一个议题是领域对象的继承
让领域对象实现继承的好处是不言而喻的,可以使用到多态等OO带来的好处。相对的就对ORM提出了更高的要求。
我们知道映射对象树到数据库有三种经典的实现方式:Table Per Type、Table Per Hierarchy和Table Per Concrete class,这次我们来实践最简单的一种:Table Per Hierarchy。
回想我们上一次的类:
[code]public class Hero : IEntity { public int Id { get; set; } public string Name { get; set; } //public bool IsSuperHero { get; set; } public virtual Race Race { get; set; } } public class SuperHero : Hero { }
[/code]
在EF Code First中这种单表继承的映射关系是这样来写的:
Map<Hero>(hero => hero.Requires(ColumnNameMappingStrategy.Value.To("IsSuperHero")).HasValue(false)).ToTable(tableNameMappingStrategy.To("Hero")); Map<SuperHero>(hero => hero.Requires(ColumnNameMappingStrategy.Value.To("IsSuperHero")).HasValue(true)).ToTable(tableNameMappingStrategy.To("Hero"));
另外两种方式的实现也不复杂,可以参考这里。这个实例还是CTP5的API,跟4.1最终版有些区别不过应该影响不大。
今天最后的议题是事物
可以用TransactionScope来管理,虽然看起来有些浪费,毕竟例子中不涉及Transaction传播,连DbContext都只有一个实例。代码如下:
[HttpPost] public ActionResult Edit(TEntity entity) { try { using (var scope = new TransactionScope()) { ModelRepository.Update(entity); scope.Complete(); } return RedirectToAction("Index"); } catch { return View(); } }
Spring实际上也可以用AOP的方式管理TransactionScope。不过我倾向于手动管理Transaction。
代码下载
本次的代码请参考这个changeset
今天就到这里-v-
相关文章推荐
- 一起谈.NET技术,Entity Framework 4.1 Code First 学习之路(二)
- Entity Fram“.NET研究”ework 4.1 Code First 学习之路(二)
- Entity Framework 4.1 Code First 学习之路
- Entity Framework 4.1 Code First 学习之路(一)
- Entity Framework 4.1 Code First 学习之路(二)
- 在ASP“.NET技术”.NET MVC3中使用EFCodeFirst 1.0
- EF 4.1 Code First Walkthrough 学习摘要
- .NET学习之路----我对P/Invoke技术的理解(一)
- 一起谈.NET技术,在ASP.NET MVC3中使用EFCodeFirst 1.0
- Entity Framework 4.1 Code-First 学习笔记
- Apache CXF学习- 利用jaxws创建一个"code first" web service 推荐
- java学习路线-Java技术人员之路从0基础到高级
- 学习ASP.NET MVC(八)——“Code First Migrations ”工具
- 技术学习网站收藏推荐(CodeProject , MSDN 等)
- 小菜的ArcObjects学习之路------ ArcGIS COM类型在.Net中继承
- 我的.Net学习之路三——多态虚方法
- 使用.Net的CodeDOM技术实现语言无关的Code Wizard
- 《C++primer(第五版)》学习之路-第十九章:特殊工具与技术
- 总结必须学习的10项.NET技术