ГЛАВНАЯ     АРХИВ     НАПИСАТЬ АДМИНУ     ПОДПИСАТЬСЯ НА RSS     ВОЙТИ      

Поиск

Категории

Облако тегов

acer ado.net amd asp.net c sharp c# cms css exceptions google html ipad iphone it бизнес javascript jquery linq microsoft mysql net nokia nokia lumia samsung seo silverlight sql surface tsql windows 8 windows blue windows phone windows rt xna безопасность библиотека вопросы на собеседовании интересные проекты интернет интернет магазин исключения книга книги компьютерная безопасность компьютерные игры контролы курсы по программированию логированние исключений мобильные приложения монетизация сайтов наушники новости новости it новости microsoft новости интернет новости технологий ноутбук ноутбуки обработка исключений оптимизация острова периферия планшет планшеты поддержка сайтов поисковое продвижение программы продвижение продвижение сайта продвижение сайтов рабство разработка игр разработка сайтов раскрутка сайта рекламные технологии смартфон смартфоны собеседование создание сайтов средства разработки туризм фриланс хостинг яндекс
  << Предыдущий пост       Следующий пост >>  
От: inbruk
24. декабря 2014 10:52


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)); 
        }
    }
}

Похожие записи


Каким способом удачно сделать выбор совершая покупку между компьютером и ноутбуком
Сейчас купить компьютер в минске, либо в любом ином городишке – не вызовет затруднений. А вот правильно подобрать из многообразия техники не так-то просто и легко. Традиционно, покупатели выбирают из двух типов компьютеров – ноутбук или стационарный компьютер. Между ними существует ряд различий, и у первого и у второго есть много положительных сторон. Подбирать следу...

Вопросы на собеседовании C#, Net, ASP.NET, SQL
Продолжая тему вопросов на собеседовании. Нашел еще одну подборку. Оригинал лежит здесь . Перенес, чтобы не затерялось. Есть вполне вменяемые ответы (хотя, на некоторые вопросы ответил бы по-другому). Ответы находятся после списка вопросов, я их не менял. 23. Что такое шаблон проектирования Model/View/Controller? Как и зачем его применяют? 2...

Как передать функцию как параметр в другую функцию на JavaScript ?
Часто бывают ситуации, когда хочется (было бы удобно) передать функцию как параметр в другую функцию, и там использовать. И все это заметьте на JavaScript-е. Рассмотрим пример того, как это можно сделать. [code:c#] <script type="text/javascript"> function fOne(p1, p2) { p1(p2); } /* function literal */ var fTwo = function (m1) { alert(m1 ...

Добавить комментарий




biuquote
  • Комментарий
  • Предпросмотр
Loading


  Сохранить комментарий