Шаблон репозитория и сопоставление между моделями доменов и Entity Framework

Мои репозитории имеют дело с и обеспечивают постоянство для богатой доменной модели. Я не хочу раскрывать анемичные сущности данных Entity Framework моим бизнес-уровням, поэтому мне нужен какой-то способ сопоставления между ними.

В большинстве случаев построение экземпляра модели предметной области из объекта данных требует использования параметризованных конструкторов и методов (поскольку он богат). Это не так просто, как соответствие свойства / поля. AutoMapper может использоваться для противоположной ситуации (сопоставление с объектами данных), но не при создании моделей предметной области.

Ниже приводится ядро моего шаблона хранилища.

EntityFrameworkRepository Класс работает с двумя универсальными типами:

TDomainModel: Богатая доменная модельTEntityModel: Сущность данных Entity Framework

Определены два абстрактных метода:

ToDataEntity(TDomainModel): Преобразовать в объекты данных (дляAdd() а такжеUpdate() методы)ToDomainModel(TEntityModel): Построить доменные модели (дляFind() метод).

Конкретные реализации этих методов будут определять отображение, необходимое для рассматриваемого хранилища.

public interface IRepository<T> where T : DomainModel
{
    T Find(int id);
    void Add(T item);
    void Update(T item);
}

public abstract class EntityFrameworkRepository<TDomainModel, TEntityModel> : IRepository<TDomainModel>
    where TDomainModel : DomainModel
    where TEntityModel : EntityModel
{
    public EntityFrameworkRepository(IUnitOfWork unitOfWork)
    {
        // ...
    }

    public virtual TDomainModel Find(int id)
    {
        var entity = context.Set<TEntityModel>().Find(id);

        return ToDomainModel(entity);
    }

    public virtual void Add(TDomainModel item)
    {
        context.Set<TEntityModel>().Add(ToDataEntity(item));
    }

    public virtual void Update(TDomainModel item)
    {
        var entity = ToDataEntity(item);

        DbEntityEntry dbEntityEntry = context.Entry<TEntityModel>(entity);

        if (dbEntityEntry.State == EntityState.Detached)
        {
            context.Set<TEntityModel>().Attach(entity);

            dbEntityEntry.State = EntityState.Modified;
        }
    }

    protected abstract TEntityModel ToDataEntity(TDomainModel domainModel);
    protected abstract TDomainModel ToDomainModel(TEntityModel dataEntity);
}

Вот базовый пример реализации репозитория:

public interface ICompanyRepository : IRepository<Company>
{
    // Any specific methods could be included here
}

public class CompanyRepository : EntityFrameworkRepository<Company, CompanyTableEntity>, ICompanyRepository
{
    protected CompanyTableEntity ToDataEntity(Company domainModel)
    {
        return new CompanyTable()
        {
            Name = domainModel.Name,
            City = domainModel.City
            IsActive = domainModel.IsActive
        };
    }

    protected Company ToDomainModel(CompanyTableEntity dataEntity) 
    {
        return new Company(dataEntity.Name, dataEntity.IsActive)
        {
            City = dataEntity.City
        }
    }
}

Проблема:

A Company может состоять из многихDepartments, Если я хочу загрузить их сCompanyRepository при полученииCompany тогда где бы я определил отображение междуDepartment иDepartmentDataEntity?

Я мог бы предоставить больше методов отображения вCompanyRepository, но это скоро станет грязным. Скоро в системе появятся дублированные методы отображения.

Как лучше подходить к вышеуказанной проблеме?

Ответы на вопрос(6)

Ваш ответ на вопрос