• 开发笔记:用不用UnitOfWork以及Repository返回什么集合类型


    这2天实际开发中明确的东西,在这篇博文中记录一下。

    之前对是否需要自己封装UnitOfWork有些犹豫,因为Entity Framework就是一个UnitOfWork实现, 自己再封装一下显得有些多余。

    但是在这次开发中,把涉及数据库操作的实现代码放在最后写,先完成其他层的代码。这种情况下,根本用不了EF,只能先Fake出一个UnitOfWork,这时必须要进行UnitOfWork的封装。

    所以,定义了IUnitOfWork接口并实现了一个FakeUnitOfWork,简化的示例代码如下:

    IUnitOfWork

    public interface IUnitOfWork : IDisposable
    {
        TEntity Add<TEntity>(TEntity entity) where TEntity : class; 
        Task CommitAsync();
    }

    FakeUnitOfWork

    public class FakeUnitOfWork : IUnitOfWoerk
    {
        private IList _entities = new List<object>();
    
        public TEntity Add<TEntity>(TEntity entity) where TEntity : class
        {
            var property = typeof(TEntity).GetProperty("ID");
            if(property != null)
            {
                property.SetValue(entity, new Random().Next());
            }
            _entities.Add(entity);            
            return entity;
        } 
    
        public async Task CommitAsync()
        {
            var bits = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(_entities, 
                Newtonsoft.Json.Formatting.Indented));
            using (var fs = new FileStream(
                path: @"C:	empFakeUnitOfWork.json", 
                mode: FileMode.Create, 
                access: FileAccess.Write, 
                share: FileShare.None, 
                bufferSize: 4096, 
                useAsync: true))
            {
                await fs.WriteAsync(bits, 0, bits.Length);
            }
        }
    }

    到写数据库操作代码时,基于EF实现一下IUnitOfWork接口即可。

    接下来是Repository返回集合类型的问题。

    之前Repository接口多数返回的是IList<T>,这样使用的一个考虑就是让涉及数据库查询的操作尽量在Repository层完成,避免在Application层进行数据库查询操作。

    但是今天在Application层的Service中用到了AutoMapper的Project功能,Project的好处是让EF生成的SQL只查询DTO中的字段,但Project扩展方法是针对(且只能针对)IQureryable<T>接口的,所以不得不将Repository接口的返回类型改为IQureryable<T>。

    考虑到Project的巨大吸引力以及为了保持Repository返回类型的一致,以后Repository就都统一返回IQureryable<T>吧。

    示例代码如下:

    IBlogCategoryRepository

    public interface IBlogCategoryRepository
    {
        Task<IQueryable<BlogCategory>> GetCategoriesByBlogId(int blogId, bool activeOnly);
    }

    BlogCategoryService

    public class BlogCategoryService : IBlogCategoryService
    {
        private IBlogCategoryRepository _blogCategoryRepository;
    
        public BlogCategoryServiceImp(IBlogCategoryRepository blogCategoryRepository)
        {
            _blogCategoryRepository = blogCategoryRepository;
        }
    
        async Task<IList<BlogCategoryDto>> IBlogCategoryService.GetCategoriesByBlogId(int blogId, bool activeOnly)
        {
            return (await _blogCategoryRepository
                .GetCategoriesByBlogId(blogId, activeOnly))
                .Project()
                .To<BlogCategoryDto>()
                .ToList();
        }
    }
  • 相关阅读:
    Oracle数据库面试题【转载】
    年龄计算周岁
    丈夫的权力与妻子的职业水平
    JDK 8 and JRE 8 Supported Locales
    一笔画 奇点 偶点
    流水行船问题
    PL/SQL LOOP SAMPLE
    OpenCV——识别各省份地图轮廓
    OpenCV——轮廓面积及长度计算
    树莓派3安装opencv2程序无法运行
  • 原文地址:https://www.cnblogs.com/dudu/p/4515485.html
Copyright © 2020-2023  润新知