Репозиторий против доступа к данным - PullRequest
8 голосов
/ 06 мая 2010

В контексте n-уровневого приложения, есть ли разница между тем, что вы считаете вашими классами доступа к данным, и вашими репозиториями?

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

Что вы, ребята, думаете? Также вы видите какие-либо изменения в сценарии Linq to XML (при условии, что вы изменили контекст для соответствующего XDocument)?

Ура Энтони

UPDATE:

Это способ, которым я обычно реализовывал вещи ранее:

public class TermBl : ITermBl
{
    public IEnumerable<ITerm> GetAll(IListParameter criteria)
    {
        //Any pre business logic

        var dataLayer = this.CreateDataLayer();
        var result = dataLayer.GetAll(criteria);

        //Any post business logic

        return result;
    }

    ... Other methods
}

public class TermDa : ITermDa
{
    public IEnumerable<ITerm> GetAll(IListParameter criteria)
    {
        //Linq query
        var dataResult = ....ToList()

        var mappedResult = this.FromDataToDomain(dataResult);   
        //Note the mapping isn't done in this object, the actual 
        //  mapping is handled by a separate component

        return mappedResult;
    }

    ... Other methods
}

Видите ли вы какие-либо присущие здесь проблемы с шаблоном в целом ...

Что касается хранилища, в котором я думал об использовании, то вместо запроса непосредственно в методе GetAll TermDa я бы изменил его так, чтобы он выглядел примерно так:

public class TermDa : ITermDa
{
    public IEnumerable<ITerm> GetAll(IListParameter criteria)
    {
        var repository = this.CreateRepository();
        var dataResult = repository.GetAll(..., criteria).ToList();

        var mappedResult = this.FromDataToDomain(dataResult);

        return mappedResult;
    }

    ... Other methods
}

public class TermRepository : ITermRepository 
{
    public IQueryable<ITerm> GetAll(IMyContext context, IListParameter criteria)
    {
        //Linq query
        return  ...;
    }

    ... Other queries
}

Вы, ребята, видите, как это работает или нет на самом деле ... С хранилищем или без него я вижу, что любое из вышеперечисленного полностью защищает бизнес-уровень от знания чего-либо об используемых методах / технологиях доступа к данным ...

Ответы [ 2 ]

9 голосов
/ 06 мая 2010

Да, есть большая разница.

  • A DAL (например, шлюз табличных данных) представляет собой концепцию базы данных . Он отвечает за выдачу запросов к базе данных и возврат наборов записей.

  • A хранилище является концепцией domain . Он отвечает за прием структурированных запросов и возврат строго типизированных объектов .

Очень разные на практике.


Обновление:

Вопрос, кажется, отражает значительную путаницу, поэтому позвольте мне уточнить с примером кода. Вот дизайн, который вы могли бы использовать, если бы вы не использовали ORM и вместо этого делали все свои собственные сопоставления. Это не код производственного качества, он предназначен только для образовательных целей:

Доступ к данным:

public interface IOrderData
{
    IDataReader GetOrder(int orderID);
}

public interface IOrderDetailData
{
    IDataReader GetOrderDetails(int orderID);
}

public interface IProductData
{
    IDataReader GetProduct(int productID);
}

Домен:

public class Order
{
    public int ID { get; set; }
    public DateTime Date { get; set; }
    public OrderStatus Status { get; set; }
    // etc.
    public IList<OrderDetail> Details { get; set; }
}

public class OrderDetail
{
    public int ID { get; set; }
    public Product Product { get; set; }
    public int Quantity { get; set; }
}

Отображение:

public interface IDataMapper
{
    Order MapOrder(IDataRecord record);
    OrderDetail MapOrderDetail(IDataRecord record);
    Product MapProduct(IDataRecord record);
}

Repository:

public interface IOrderRepository
{
    Order GetOrder(int orderID);
}

public class OrderRepository
{
    // These get initialized in the constructor
    private readonly IOrderData orderData;
    private readonly IOrderDetailData orderDetailData;
    private readonly IProductData productData;
    private readonly IDataMapper mapper;

    public Order GetOrder(int orderID)
    {
        Order order;
        using (IDataReader orderReader = orderData.GetOrder(orderID))
        {
            if (!orderReader.Read())
                return null;
            order = mapper.MapOrder(orderReader);
        }
        using (IDataReader detailReader = 
            orderDetailData.GetOrderDetails(orderID))
        {
            while (detailReader.Read())
            {
                OrderDetail detail = mapper.MapOrderDetail(detailReader);
                detail.Product = ...;  // Omitted for brevity, more reading/mapping
                order.Details.Add(detail);
            }
        }
        return order;
    }
}

Теперь это имеет больше смысла? DAL имеет дело с данными. Конкретный репозиторий может инкапсулировать классы доступа к данным, но абстрактный репозиторий (его открытый интерфейс) работает только с классами домена.

Еще раз я просто напомню читателям, что это даже не близко к коду производственного качества, и что большинство приложений сегодня используют ORM или, по крайней мере, некоторую лучшую форму автоматического отображения. Это только для иллюстрации.

1 голос
/ 06 мая 2010

У вас, кажется, хорошая ручка. «Классы доступа к данным» могут принимать разные формы. Это какой-то класс, имеющий отношение к доступу к данным. Ваш репозиторий является (A) шаблоном для обработки вашей персистентности данных и (B) местом в вашей схеме доступа к данным (если вы внедряете репозиторий).

Сложной задачей в вашей стратегии доступа к данным является обеспечение гибкости и возможности многократного использования одновременно. В то же время, будучи эффективным. В то же время, работая с вашей бизнес-логикой, вы будете отделены, но при этом будете связными . Tricky.

Репозиторий - это шаблон, который призван помочь со всем этим балансом. Ваш код для перевода БД (или чего-либо еще) в / из классов сущностей находится в одном месте для каждой сущности. Ваши «Классы доступа к данным» могут состоять из ваших классов репозитория, а также классов, которые фактически работают с SQL. Вы, конечно, не должны делать все SQL-лжи в каждом из ваших классов репозитория.

Пример: вы могли бы начать с неэффективного, но легкого отражения, чтобы заполнить объекты-сущности, практически не выполняя работу в ваших классах репозитория; позже вы можете сделать его более эффективным для больших объектов, но это полностью скрыто от других частей вашей системы. А потом вы перенесете некоторую конфигурацию в XML, но остальная часть вашей системы не имеет представления об этом изменении.

LINQ-to-sql и платформа Entity действительно используют шаблон репозитория, потому что то, что возвращают классы репозитория, на самом деле является IQuerable этой сущности. Бизнес-классы могут применять дополнительные критерии, и эти критерии фактически применяются к SQL, при этом обеспечивая полную инкапсуляцию от постоянства данных. Это серьезно круто.

...