簡體   English   中英

如何在EF,Autofac和通用數據存儲庫中使用DTO?

[英]How do I use DTO's with EF, Autofac, and a generic data repository?

如何在EF,Autofac和通用數據存儲庫中使用DTO?

我正在設置一個新項目並配置我的DI / IoC(Autofac),使用通用存儲庫通過EF進行數據訪問,並創建了一個OData服務端點ContentTypesController

這是控制器的頂部:

public class ContentTypesController : ODataController, IContentTypesController
{

    // add repository reference
    private readonly IRepository<ContentType> _repository;

    private ProjectV001Context _db = new ProjectV001Context();

    /// <summary>
    /// Constructor - setup for DI
    /// </summary>
    /// <param name="contentTypeRepository"></param>
    public ContentTypesController(IRepository<ContentType> repository)
    {
        _repository = repository;
    }

    // GET odata/ContentTypes
     [Queryable]
    public Task<IQueryable<ContentType>> Get(ODataQueryOptions<ContentType> options)
    {
        // mock
        var userId = 102;
        //var unitOfWork = new Repository.UnitOfWork(_db);   <-- removed from the original question
        var result = _repository.Query()
            .Filter(u => u.UserId == userId)
            .GetAsync();

        return result;
    }

ContentType是Project.DAL.Data.Models中的EF類,它包含客戶端不需要查看/使用的字段 - 即。 用戶身份。 在插入或更新方法時,將以實際方式設置此字段的值。

我的DTO位於Project.Core.ContentTypes中。

1)我在這里正確使用工作單元模式嗎?

2)我希望我的方法返回DTO,而不是實際實體對象的所有字段。 我該如何設置?

- 更新 -

在之前的項目(和不同的存儲庫)中,我實現了UoW,如下所示:

public class ContentTypesController:ODataController {private ProjectDbContext _db = new ProjectDbContext();

public IEnumerable<ContentType> Get(ODataQueryOptions<ContentType> options)
{
    var unitOfWork = new Project.Repository.UnitOfWork(_db);

    var contentTypes = options.ApplyTo(unitOfWork.Repository<ContentType>().Queryable
        .OrderBy(c => c.Description))
        .Cast<ContentType>().ToList();

    unitOfWork.Save();      // includes Dispose()

    return contentTypes;
}

那么你實際上並沒有使用UnitOfWork模式; 只是通用的存儲庫模式。 至於返回DTO,請查看Factory模式(我使用AutoMapper)。 您可以創建您的dtos並使用automapper作為工廠來獲取您的實體並轉換為dtos或您的dtos並轉換為實體。 配置AutoMapper非常簡單,如下所示:

Mapper.CreateMap<ContentType, ContentTypeDto>();

並實際將ContentType映射到ContentTypeDto(假設您的屬性名稱匹配):

var dto = Mapper.Map<ContentType, ContentTypeDto>(contentTypeEntity);

至於工作單元:除非你計划在某個時候更換你的ORM,否則沒有使用它。 但如果你真的想要它,那很簡單:

public class UnitOfWork : IUnitOfWork
{
    private readonly IDbContext _context;
    private readonly Dictionary<Type, object> _repos;

    public IRepository<T> GetRepository<T>() {
        if (_repos.ContainsKey(typeof (T)))
            return _repos[typeof (T)] as IRepository<T>;

        var repo = new Repository(_context);
        _repos.Add(typeof (T), repo);

        return repo;
    }

    public int SaveChanges() {
        return _context.SaveChanges();
    }

    dispose stuff - make sure to dispose your context
}

IUnitOfWork實現了IDisposable並定義了GetRepository()和SaveChanges()。

您還必須創建IDbContext,它只定義Set,SaveChanges(),並實現IDisposable。

然后,您可以將IUnitOfWork注入到控制器中,並使用GetRepository()為您的控制器檢索正確的存儲庫。 這樣,所有存儲庫共享1個單獨的上下文。

實現通用存儲庫和工作單元類示例大約是此頁面的一半。 唯一不同的是他們的UnitOfWork不是通用的,但我向你展示了上述內容。

編輯:我剛剛注意到你從你的存儲庫中獲得了一個UnitOfWork:

var unitOfWork = new Repository.UnitOfWork(_db);
var result = unitOfWork.Repository<ContentType>()...

我不確定這里發生了什么。 你的UnitOfWork應該放棄你的存儲庫,但看起來你的存儲庫給你的工作單元,然后你的UnitOfWork給你一個存儲庫? 你介意分享你的存儲庫嗎? 我相信要正確實現UnitOfWork,您需要編輯您的存儲庫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM