一步一步学习ASP.NET MVC3 &EF Code First CTP 5&DI(一)

    技术2025-12-12  12

    一,摘要

    本篇文章我们将使用ASP.NET MVC3,Razor,EF Code First创建Web应用程序.覆盖Unity2.0,泛型Repository以及EF Code First的工作单元.需要使用到的工具如下:

    1.ASP.NET MVC 3 2.EF Code First CTP5 3.Unity2.0

    二,安装工具

    安装好Visual Studio2010后继续安装MVC3(http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d2928bc1-f48c-4e95-a064-2a455a22c8f6),NuGet(http://nuget.codeplex.com/)

    三,建立程序

    1.打开Visual Studio2010选择选择新建ASP.NET MVC 3 Web Application,取名叫MVC3DIApplication:

    点确认后弹出选择框如下: 点OK,创建应用程序.

    下面添加EF CTP5与Unity2.0,在刚建立的项目上右键,选择添加类库包引用,点击左边的online,在搜索框里输入Unity,找到Unity后点install.,安装成功后(图二)它自动把需要的程序集加入到项目中(图三):

    然后继续搜索EFCodeFirst并安装:

    三,建立领域模型

    1.添加一个类库,命名MVC3DIApplication.Domain,然后在里面添加文件夹Entities,在文件夹里添加实体模型类 Category.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; 5: using System.ComponentModel.DataAnnotations; 6:  7: namespace MyFinance.Domain 8: { 9: public class Category 10: { 11:  12: public int CategoryId { get; set; } 13:  14: [Required(ErrorMessage = "Name Required")] 15: [StringLength(25, ErrorMessage = "Must be less than 25 characters")] 16: public string Name { get; set;} 17: public string Description { get; set; } 18: public virtual ICollection Expenses { get; set; } 19: } 20: }

    Expense.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5:  6: namespace MVC3DIApplication.Domain.Entities 7: { 8: public class Expense 9: { 10: public int ExpenseId { get; set; } 11: public string Transaction { get; set; } 12: public DateTime Date { get; set; } 13: public double Amount { get; set; } 14: public int CategoryId { get; set; } 15: public virtual Category Category { get; set; } 16: } 17: }

    2.继续添加类库MVC3DIApplication.Data,在其下新建一个叫MyFinanceContext的类,该类继承自DbContext,用来映射我们的模型到数据库表

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using System.Data.Entity; 6: using MVC3DIApplication.Domain.Entities; 7:  8: namespace MVC3DIApplication.Data 9: { 10: public class MyFinanceContext : DbContext 11: { 12: public MyFinanceContext() : base("MyFinance") { } 13: public DbSet Categories { get; set; } 14: public DbSet Expenses { get; set; } 15: public virtual void Commit() 16: { 17: base.SaveChanges(); 18: } 19: } 20: }

    3.修改Web.comfig:

    1: <connectionStrings> 2: <add name="MyFinance" connectionString="data source=./MSSQLSERVER2008;Initial Catalog=MVC3DI;Persist Security Info=True;User ID=sa;Password=suzhi921;" providerName="System.Data.SqlClient" /> 3: <add name="ApplicationServices" connectionString="data source=./SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|aspnetdb.mdf;User Instance=true" providerName="System.Data.SqlClient" /> 4: connectionStrings>

    四,建立泛型Repository

    MVC3DIApplication.Data类库下建立Infrastructure文件夹,在里面添加类IRepository.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5:  6: namespace MVC3DIApplication.Data.Infrastructure 7: { 8: public interface IRepository where T : class 9: { 10: void Add(T entity); 11: void Delete(T entity); 12: void Delete(Func predicate); 13: T GetById(long Id); 14: T Get(Func where); 15: IEnumerable GetAll(); 16: IEnumerable GetMany(Func bool> where); 17: } 18: }

    IDatabaseFactory.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5:  6: namespace MVC3DIApplication.Data.Infrastructure 7: { 8: public interface IDatabaseFactory : IDisposable 9: { 10: MyFinanceContext Get(); 11: } 12: }

    RepositoryBase.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using System.Data.Entity; 6:  7: namespace MVC3DIApplication.Data.Infrastructure 8: { 9: public abstract class RepositoryBase where T : class 10: { 11: private MyFinanceContext dataContext; 12: private readonly IDbSet dbset; 13: protected RepositoryBase(IDatabaseFactory databaseFactory) 14: { 15: DatabaseFactory = databaseFactory; 16: dbset = DataContext.Set (); 17: } 18:  19: protected IDatabaseFactory DatabaseFactory 20: { 21: get; 22: private set; 23: } 24:  25: protected MyFinanceContext DataContext 26: { 27: get { return dataContext ?? (dataContext = DatabaseFactory.Get()); } 28: } 29: public virtual void Add(T entity) 30: { 31: dbset.Add(entity); 32: } 33:  34: public virtual void Delete(T entity) 35: { 36: dbset.Remove(entity); 37: } 38: public void Delete(Func where) 39: { 40: IEnumerable objects = dbset.Where ( where).AsEnumerable(); 41: foreach (T obj in objects) 42: dbset.Remove(obj); 43: } 44: public virtual T GetById(long id) 45: { 46: return dbset.Find(id); 47: } 48:  49: public virtual IEnumerable GetAll() 50: { 51: return dbset.ToList(); 52: } 53: public virtual IEnumerable GetMany(Func bool> where) 54: { 55: return dbset.Where(where).ToList(); 56: } 57: public T Get(Func where) 58: { 59: return dbset.Where(where).FirstOrDefault (); 60: } 61: } 62: }

    五,工作单元

    工作单元主要用来维护受Business transaction影响的对象以及并发等问题 MVC3DIApplication.Data类库的Infrastructure下建立IUnitOfWork.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5:  6: namespace MVC3DIApplication.Data.Infrastructure 7: { 8: public interface IUnitOfWork 9: { 10: void Commit(); 11: } 12: }

    UnitOfWork.cs:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5:  6: namespace MVC3DIApplication.Data.Infrastructure 7: { 8: public class UnitOfWork : IUnitOfWork 9: { 10: private readonly IDatabaseFactory databaseFactory; 11: private MyFinanceContext dataContext; 12:  13: public UnitOfWork(IDatabaseFactory databaseFactory) 14: { 15: this.databaseFactory = databaseFactory; 16: } 17:  18: protected MyFinanceContext DataContext 19: { 20: get { return dataContext ?? (dataContext = databaseFactory.Get()); } 21: } 22:  23: public void Commit() 24: { 25: DataContext.Commit(); 26: } 27: } 28: }

    六,Category Repository

    MVC3DIApplication.Data类库的下建立Repositories文件夹,里面存储我们的Repositories,下面简历CategoryRepository:

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using MVC3DIApplication.Data.Infrastructure; 6: using MVC3DIApplication.Domain.Entities; 7:  8: namespace MVC3DIApplication.Data.Repositories 9: { 10: public class CategoryRepository : RepositoryBase , ICategoryRepository 11: { 12: public CategoryRepository(IDatabaseFactory databaseFactory) 13: : base(databaseFactory) 14: { 15: } 16: } 17: public interface ICategoryRepository : IRepository 18: { 19: } 20: }

    如果我们有额外的方法,那么我们能定义在上面的Repository里.

    七,使用Unity2.0

    我们为Unity创建一个自定义的生命周期管理器去存储当前上下文的容器,同时创建控制器工厂

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; 5: using Microsoft.Practices.Unity; 6: using System.Web.Mvc; 7: using System.Web.Routing; 8:  9: namespace MVC3DIApplication.IoC 10: { 11: public class UnityControllerFactory : DefaultControllerFactory 12: { 13: IUnityContainer container; 14: public UnityControllerFactory(IUnityContainer container) 15: { 16: this.container = container; 17: } 18: protected override IController GetControllerInstance(RequestContext reqContext, Type controllerType) 19: { 20: IController controller; 21: if (controllerType == null) 22: throw new HttpException( 23: 404, String.Format( 24: "The controller for path '{0}' could not be found" + 25: "or it does not implement IController.", 26: reqContext.HttpContext.Request.Path)); 27:  28: if (!typeof(IController).IsAssignableFrom(controllerType)) 29: throw new ArgumentException( 30: string.Format( 31: "Type requested is not a controller: {0}", 32: controllerType.Name), 33: "controllerType"); 34: try 35: { 36: //controller = MvcUnityContainer.Container.Resolve(controllerType) 37: // as IController; 38: controller = container.Resolve(controllerType) as IController; 39: } 40: catch (Exception ex) 41: { 42: throw new InvalidOperationException(String.Format( 43: "Error resolving controller {0}", 44: controllerType.Name), ex); 45: } 46: return controller; 47: } 48:  49: } 50: public class HttpContextLifetimeManager : LifetimeManager, IDisposable 51: { 52: public override object GetValue() 53: { 54: return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName]; 55: } 56: public override void RemoveValue() 57: { 58: HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName); 59: } 60: public override void SetValue(object newValue) 61: { 62: HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue; 63: } 64: public void Dispose() 65: { 66: RemoveValue(); 67: } 68: } 69: }

    配置Unity:

    1: protected void Application_Start() 2: { 3: AreaRegistration.RegisterAllAreas(); 4: RegisterGlobalFilters(GlobalFilters.Filters); 5: RegisterRoutes(RouteTable.Routes); 6: IUnityContainer container = GetUnityContainer(); 7: DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 8: } 9:  10: private IUnityContainer GetUnityContainer() 11: { 12: //Create UnityContainer 13: IUnityContainer container = new UnityContainer() 14: .RegisterType ( new HttpContextLifetimeManager ()) 15: .RegisterType ( new HttpContextLifetimeManager ()) 16: .RegisterType ( new HttpContextLifetimeManager ()); 17: return container; 18: }

    八,建立控制器

    1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; 5: using System.Web.Mvc; 6: using MyFinance.Data; 7: using MyFinance.Data.Infrastructure; 8: using MyFinance.Domain; 9: using MyFinance.Helpers; 10: using MyFinance.Service; 11: namespace MyFinance.Web.Controllers 12: { 13: 14: public class CategoryController : Controller 15: { 16: private readonly ICategoryRepository categoryRepository; 17: private readonly IUnitOfWork unitOfWork; 18: 19: public CategoryController(ICategoryRepository categoryRepository, IUnitOfWork unitOfWork) 20: { 21: this.categoryRepository = categoryRepository; 22: this.unitOfWork = unitOfWork; 23: } 24: public ActionResult Index() 25: { 26: var categories = categoryRepository.GetAll(); 27: return View(categories); 28: } 29: [HttpGet] 30: public ActionResult Edit(int id) 31: { 32: var category = categoryRepository.GetById(id); 33: return View(category); 34: } 35: 36: [HttpPost] 37: public ActionResult Edit(int id, FormCollection collection) 38: { 39: var category = categoryRepository.GetById(id); 40: if (TryUpdateModel(category)) 41: { 42: unitOfWork.Commit(); 43: return RedirectToAction("Index"); 44: } 45: else return View(category); 46: } 47: 48: [HttpGet] 49: public ActionResult Create() 50: { 51: var category = new Category(); 52: return View(category); 53: } 54: 55: [HttpPost] 56: public ActionResult Create(Category category) 57: { 58: if (!ModelState.IsValid) 59: { 60: return View("Create", category); 61: } 62: categoryRepository.Add(category); 63: unitOfWork.Commit(); 64: return RedirectToAction("Index"); 65: } 66: 67: [HttpPost] 68: public ActionResult Delete(int id) 69: { 70: var category = categoryRepository.GetById(id); 71: categoryRepository.Delete(category); 72: unitOfWork.Commit(); 73: var categories = categoryRepository.GetAll(); 74: return PartialView("CategoryList", categories); 75: 76: } 77: } 78: }

    九,建立视图

    CategoryList.cshtml:

    1: @using MVC3DIApplication.Domain.Entities; 2: @model IEnumerable<Category> 3: <table> 4: <tr> 5: <th>Actions th> 6: <th>Name th> 7: <th>Description th> 8: tr> 9: @foreach (var item in Model) { 10: <tr> 11: <td> 12: @Html.ActionLink("Edit", "Edit",new { id = item.CategoryId }) 13: @Ajax.ActionLink("Delete", "Delete", new { id = item.CategoryId }, 14: new AjaxOptions { Confirm = "Delete Expense?", HttpMethod = "Post", 15: UpdateTargetId = "divCategoryList" }) 16: td> 17: <td> 18: @item.Name 19: td> 20: <td> 21: @item.Description 22: td> 23: tr> 24: 25: } 26:  27: table> 28: <p> 29: @Html.ActionLink("Create New", "Create") 30: p> Index.cshtml: 1: @model IEnumerable<MVC3DIApplication.Domain.Entities.Category> 2: @{ 3: ViewBag.Title = "Index"; 4: } 5: <h2>Category List h2> 6: <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"> script> 7: <div id="divCategoryList"> 8: @Html.Partial("CategoryList", Model) 9: div>

    Create.cshtml:

    1: @model MVC3DIApplication.Domain.Entities.Category 2:  3: @{ 4: ViewBag.Title = "Create"; 5: } 6:  7: <h2>Create h2> 8:  9: <script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> script> 1:  2:
    最新回复(0)