Сегодня 21 декабря, суббота ГлавнаяНовостиО проектеЛичный кабинетПомощьКонтакты Сделать стартовойКарта сайтаНаписать администрации
Поиск по сайту
 
Ваше мнение
Какой рейтинг вас больше интересует?
 
 
 
 
 
Проголосовало: 7277
Кнопка
BlogRider.ru - Каталог блогов Рунета
получить код
coding4.net
coding4.net
Голосов: 1
Адрес блога: http://www.coding4.net/
Добавлен: 2012-06-11 20:16:46
 

Как быстро сделать CRUD ?

2014-12-24 10:52:00 (читать в оригинале)


C sharp

Очень многие программисты во многих проектах пишут реализацию CRUD для разных сущностей. После того как я написал изрядное количество такого кода и мне надоело решать постоянно похожие задачи. Решений быстрого создания может быть несколько. Наиболее оптимальным, видимо, является генерация с использованием шаблонов T4. У разных подходов есть свои плюсы и минусы. В этом посте расскажу об упрощении создания CRUD для сущности с использованием Generic-ов и библиотеки AutoMapper. Представленное решение, возможно, не завершенное, можно его наверное и улучшить. Но, оно способно существенно ускорить и упростить разработку. Ну или во всяком случае указать направление.

Про библиотеку AutoMapper можно почитать здесь и здесь (производительность и аналоги). Дальше идет код Generic класса для создания CRUD-ов.

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.00) в категории «Спорт»


Загрузка...Загрузка...
BlogRider.ru не имеет отношения к публикуемым в записях блогов материалам. Все записи
взяты из открытых общедоступных источников и являются собственностью их авторов.