![](/img/trans.png)
[英]How can I have a generic repository to load the data asynchronously with EF?
[英]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.