如何将实体框架中的数据访问映射到业务逻辑对象我在ASP.NETC#MVC应用程序中使用实体框架。我在数据访问层中有EF生成的对象:namespaceProject1.DataAccess{usingSystem;使用System.Collections.Generic;publicpartialclassUser{publicUser(){this.Files=newHashSet();this.Folders=newHashSet();}//...}}现在我想创建业务逻辑对象并使用数据访问对象映射它们:namespaceProject1.Logic{publicclassUser{publicintId{get;放;}}}我在数据库中有几个表。我需要使用Automapper吗?如果没有,我该如何实现映射?我一直在使用EF6从MSSQL表生成我的数据访问层,然后创建一组对象来表示我想如何与我的代码交互(或显示它),这些对象是POCO。“映射”是通过实现存储库模式来处理的。下面是一个通用接口,可帮助我确保所有回购类都遵循相同的形状。公共接口IDataRepository{IQueryableGet();TGet(intid);T添加(T对象);T更新(T对象);voidDelete(Tobj);然后,我像这样创建回购类。(使用您的UserBusiness和UserDAL类)publicclassNewRepo:IDataRepository{YourContextdb=newYourContext();publicIQueryableGet(){return(fromuindb.UserDALselectnewUserBusiness(){Id=u.Id,Name=u.Name});}publicUserBusinessGet(intid){return(fromuindb.UserDALwhereu.Id==idselectnewUserBusiness(){Id=u.Id,Name=u.Name}).FirstOrDefault();}publicOrderAdd(UserBusinessobj){UserDALu=newUserDAL();u.Name=obj.Name;db.UserDAL.Add(u);db.SaveChanges();//假设数据库正在为你生成你的Idobj.Id=u.Id;返回对象;}publicOrderUpdate(UserBusinessobj){UserDALu=newUserDAL();u.Id=obj.Id;u.Name=obj.Name;db.Entry(u).State=EntityState.Modified;db.SaveChanges();返回对象;}publicvoidDelete(UserBusinessobj){UserDALu=db.UserDAL.Where(o=>o.Id==obj.Id).FirstOrDefault();如果(u!=Null){db.Entry(u).State=EntityState.Deleted;db.SaveChanges();}}}在您的应用程序中,您现在使用repo方法而不是DBContext最后,我经常最终添加另一层与我的repos交互的“服务类”,管理业务类的内部数据......或者您可以通过将repo方法添加到他们更“聪明”。我倾向于让POCO保持愚蠢并构建服务类来获取、设置和编辑属性。是的,有一堆左右映射将一个类“转换”为另一个类,但它是内部业务逻辑类的干净分离,供以后使用。POCO转换的直接表一开始可能看起来很傻,但只要等到DBA想要规范化几个字段,或者您决定为这些简单的对象添加一个集合。能够在不破坏应用程序其余部分的情况下管理您的业务对象是无价的。编辑:下面是存储库的通用版本,可以更轻松地创建新版本。这是所有业务逻辑层类的基类:publicclassBaseEntity{publicintId{get;放;这是所有数据访问层类的基类:publicclassBaseEntityDAL{[Key][Column("Id")]publicintId{get;放;这是存储库的通用基类(注意我们在这里使用AutoMapper):受保护的只读DbSetdbSet;受保护的虚拟TDALMap(TBLLobj){Mapper.CreateMap();返回Mapper.Map(obj);}protectedvirtualTBLLMap(TDALobj){Mapper.CreateMap();返回Mapper.Map(obj);}受保护的抽象IQueryableGetIQueryable();publicBaseRepository(MyDbContextcontext,DbSetdbSet){if(context==null)thrownewArgumentNullException(nameof(context));如果(dbSet==null)抛出新的ArgumentNullException(nameof(dbSet));this.context=上下文;这个.dbSet=dbSet;}publicTBLLGet(intid){varentity=dbSet.Where(i=>i.Id==id)。FirstOrDefault();var结果=地图(实体);返回结果;}publicIQueryableGet(){返回GetIQueryable();}publicTBLLAdd(TBLLobj){varentity=Map(obj);dbSet.Add(实体);context.SaveChanges();obj.Id=entity.Id;返回对象;}publicTBLLUpdate(TBLLobj){varentity=Map(obj);context.Entry(entity).State=EntityState.Modified;context.SaveChanges();返回对象;}publicvoidDelete(TBLLobj){TDALentity=dbSet.Where(e=>e.Id==obj.Id).FirstOrDefault();if(entity!=null){context.Entry(entity).State=EntityState.Deleted;context.SaveChanges();}}}最后,当我们完成上记所有操作时,这是存储库的示例现实,非常干净://我们不能在这里使用AutoMapper,因为EntityFramework//无法处理表达式。因此需要手动//映射。Id=entity.Id,CompanyId=entity.CompanyId,ProjectId=entity.ProjectId,IndexNumber=entity.IndexNumber,ContractNumber=entity.ContractNumber,ConclusionDate=entity.ConclusionDate,Notes=entity.Notes});}publicContractRepository(MyDbContextcontext):base(context,context.Contracts){}}如果你的项目比较小,我建议你根本不要使用DTO——相反你可以使用EntityFrameworkCodeFirst并重用您跨多个层的业务实体(只需确保将您的代码优先实体放入一些公共库中)否则,您可以创建自己的转换方法或使用像AutoMapper这样的库。如果您想在业务模型设计中使用普通的旧Clr对象并将它们映射到数据库表,您可以使用实体框架的代码优先方法。在代码中,首先不会为您生成任何内容。但是,您将负责将业务对象映射到数据库表和字段。您可以通过两种方式进行基本测试:这两种方法都会为您生成相同的映射,但我更喜欢FluentApi方法,因为它提供了更强大的映射API,并使您的BO独立于数据上下文中的Any映射逻辑。但是..一旦你生成了类,这些类将被绑定并映射到你,数据库的第一个方法。所以你可以扩展这些类,因为它们是部分的。您可以在此博客中找到有关EF上不同工作流的详细信息,这将帮助您根据需要使用正确的工作流:http://blog.smartbear.com/development/choosing-the-right-entity-framework-workflow/如果您DAL和BLLUser对象是完全一样的,你可以使用这样一个函数来映射:publicvoidSetProperties(objectsource,objecttarget){vartype=target.GetType();foreach(varpropinsource.GetType().GetProperties()){varpropGetter=prop.GetGetMethod();varpropSetter=type.GetProperty(prop.Name).GetSetMethod();varvalueToSet=propGetter.Invoke(source,null);道具设定器。调用(目标,新[]{valueToSet});但是,为什么您需要一个在DAL和BLL中不同但相同的User对象?如果您需要更改User对象的属性会怎样?您必须在整个应用程序的每个实例、每个层中进行更改(紧耦合),这首先违背了DAL和BLL的目的。这是使用泛型和接口的一个非常有用的例子。因此,给定对象User示例:publicclassUser{publicintId{get;库”类或其他一些数据访问方法:publicclassDALMethods:IDALMethodswhereT:class{privateUserContext_db;privateDbSet_set;publicDALMethods(UserContextdb){_db=db;_set=_db.Set();}publicvoidCreate(Tentity){_set.Add(entity);_db.SaveChanges();}//...明确处理需要的上下文方法。}..然后你的BLL将只关注用户业务逻辑:publicclassUserBLL:IBLLMethods{privateDALMethods_repository;privateUserContext_db;publicUserBLL(){_db=newUserContext();_repository=newDALMethods(_db);}publicboolCreateUserIfNameIsBob(Useruser){//创建bobifbobif(user.Name=="Bob"){_repository.Create(user);returntrue;}//Notbobreturnfalse;}}上面的例子是故意通用的,但我认为它们说明了这一点。如果你的User对象发生变化,它不会t阻止BLL和DAL层工作,你可以使用IDALMethods类的接口来强制约束,或者使用IoC容器来进一步解耦代码。HTH以上就是C#学习教程:如何将实体框架中的数据访问映射到业务逻辑对象共享的全部内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注——本文来自网络收藏,不代表立场,如涉及侵权,请点击有权联系管理员删除。如需转载请注明出处:
