Какой рейтинг вас больше интересует?
|
Как быстро сделать CRUD ?2014-12-24 10:52:00 (читать в оригинале)Очень многие программисты во многих проектах пишут реализацию CRUD для разных сущностей.
После того как я написал изрядное количество такого кода и мне надоело решать постоянно похожие задачи.
Решений быстрого создания может быть несколько. Наиболее оптимальным, видимо, является генерация с использованием шаблонов T4.
У разных подходов есть свои плюсы и минусы. В этом посте расскажу об упрощении создания CRUD для сущности с использованием Generic-ов и библиотеки AutoMapper.
Представленное решение, возможно, не завершенное, можно его наверное и улучшить. Но, оно способно существенно ускорить и упростить разработку. Ну или во всяком случае указать направление.
using System; using System.Collections.Generic; using System.Data.Entity; using System.Data.Entity.Validation; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Threading.Tasks; using NEB.DataAccessLayer; using AutoMapper; namespace NEB.BusinessLogicLayer { public abstract class CRUDWithMappingBase<DTO, TBL, TID> where DTO : class where TBL : class { public CRUDWithMappingBase() { Mapper.CreateMap<TBL, DTO>(); Mapper.CreateMap<DTO, TBL>(); } protected TBL _lastCreatedItem = null; // получение значения автоинкрементного поля Id при создании одной записи protected abstract TID GetLastCreatedId(); // запись значения Id в DTO объект protected abstract void InsertIdInDTO(DTO dtoItem, TID idValue); protected List<DTO> ConvertTBL2DTO(List<TBL> listOfProxy) { List<DTO> result = new List<DTO>(); foreach (TBL currProxy in listOfProxy) { DTO resDTO = Mapper.Map<TBL, DTO>(currProxy); result.Add(resDTO); } return result; } public void Create(DTO newDTO) { _lastCreatedItem = Mapper.Map<DTO, TBL>(newDTO); try { NEBEntitiesContext ctx = NEBContextHandler.Get(); ctx.Set<TBL>().Add(_lastCreatedItem); ctx.SaveChanges(); } catch( DbEntityValidationException dbex) { var errs = dbex.EntityValidationErrors; throw dbex; // ловим для поиска ошибки при отладке, но прокидываем, чтобы не скрыть } TID lastCreatedId = GetLastCreatedId(); InsertIdInDTO(newDTO, lastCreatedId); } public void CreateSeveral(List<DTO> newDTOList) { try { foreach (DTO currItem in newDTOList) { Create(currItem); } } catch (DbEntityValidationException dbex) { var errs = dbex.EntityValidationErrors; throw dbex; // ловим для поиска ошибки при отладке, но прокидываем, чтобы не скрыть } } public void CreateSeveralFastWithoutIdsAquering(List<DTO> newDTOList) { try { NEBEntitiesContext ctx = NEBContextHandler.Get(); foreach (DTO currItem in newDTOList) { _lastCreatedItem = Mapper.Map<DTO, TBL>(currItem); ctx.Set<TBL>().Add(_lastCreatedItem); } ctx.SaveChanges(); } catch (DbEntityValidationException dbex) { var errs = dbex.EntityValidationErrors; throw dbex; // ловим для поиска ошибки при отладке, но прокидываем, чтобы не скрыть } } public List<DTO> ReadAll() { List<TBL> listOfProxy = NEBContextHandler.Get().Set<TBL>().ToList(); List<DTO> result = ConvertTBL2DTO(listOfProxy); return result; } protected List<DTO> ReadSeveral(Expression<Func<TBL, bool>> predicate) { List<TBL> listOfProxy = NEBContextHandler.Get(). Set<TBL>().Where(predicate).ToList(); List<DTO> result = ConvertTBL2DTO(listOfProxy); return result; } protected DTO ReadOne( Expression<Func<TBL, bool>> predicate ) { TBL dataProxyObject = NEBContextHandler.Get().Set<TBL>().SingleOrDefault( predicate ); DTO resDTO = Mapper.Map<TBL, DTO>(dataProxyObject); return resDTO; } protected void UpdateOne(DTO upDTO, Expression<Func<TBL, bool>> predicate) { NEBEntitiesContext ctx = NEBContextHandler.Get(); TBL dataProxyObject = ctx.Set<TBL>().SingleOrDefault( predicate ); Mapper.Map<DTO, TBL>(upDTO, dataProxyObject); ctx.SaveChanges(); } protected void DeleteOne(Expression<Func<TBL, bool>> predicate) { NEBEntitiesContext ctx = NEBContextHandler.Get(); TBL dataProxyObject = ctx.Set<TBL>().SingleOrDefault(predicate); ctx.Set<TBL>().Remove(dataProxyObject); ctx.SaveChanges(); } protected void DeleteSeveral(Expression<Func<TBL, bool>> predicate) { NEBEntitiesContext ctx = NEBContextHandler.Get(); List<TBL> listOfProxy = ctx.Set<TBL>().Where(predicate).ToList(); foreach (TBL currProxy in listOfProxy) { ctx.Set<TBL>().Remove(currProxy); } ctx.SaveChanges(); } } } Здесь DTO - DataTransferObject (он же POC) для передачи данных между BL и верхними слоями, TBL - прокси класс EF, TID - тип колонки (поля) идентификатора записи (строки в БД). А теперь приведен код класса CRUD созданного на основе предыдущего Generic-а. using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using SomeProject.BusinessLogicLayer; using SomeProject.DataAccessLayer; using DTO = SomeProject.Libraries.BusinessLogicLayer.DataTransferObjects; namespace SomeProject.Libraries.BusinessLogicLayer { public class LibraryCRUD : CRUDWithMappingBase<DTO.Library, tbl_libraries, Int32> { protected override Int32 GetLastCreatedId() { return _lastCreatedItem.Id; } protected override void InsertIdInDTO(DTO.Library dtoItem, Int32 idValue) { dtoItem.Id = idValue; } public LibraryCRUD() : base() { } public DTO.Library ReadOne(Int32 Id) { return this.ReadOne(x => x.Id == Id); } public List<DTO.Library> ReadSeveral(List<Int32> listOfIds) { return this.ReadSeveral(x => listOfIds.Contains(x.Id)); } public void UpdateOne(DTO.Library lib) { this.UpdateOne(lib, x => x.Id == lib.Id); } public void DeleteOne(DTO.Library lib) { this.DeleteOne(lib.Id); } public void DeleteOne(Int32 Id) { this.DeleteOne(x => x.Id == Id); } public void DeleteSeveral(List<Int32> listOfIds) { this.DeleteSeveral(x => listOfIds.Contains(x.Id)); } public DTO.Library ReadOSomeProjectySourceALISIdAndIdFromALIS(Int32 sourceALISId, String idFromALIS) { return this.ReadOne(x => x.SourceALIS == sourceALISId && x.IdFromALIS == idFromALIS); } public List<DTO.Library> ReadSeveralBySourceALISIdAndIdFromALISList( Int32 sourceALISId, List<String> listOfIds) { return this.ReadSeveral( x => x.SourceALIS == sourceALISId && listOfIds.Contains(x.IdFromALIS)); } } }
|
Категория «Программы»
Взлеты Топ 5
Падения Топ 5
Популярные за сутки
|
Загрузка...
взяты из открытых общедоступных источников и являются собственностью их авторов.