В контексте n-tier приложения, там различие между тем, чем Вы полагали бы, что Ваши классы доступа к данным и Ваши репозитории?
Я склонен думать да, но я просто хотел видеть что другая мысль. Мои взгляды состоят в том, что задание репозитория состоит в том, чтобы только содержать и выполнить сам необработанный запрос, где, поскольку класс доступа к данным создал бы контекст, выполните репозиторий (передающий в контексте), дескриптор, отображающий модель данных на модель предметной области, и возвратитесь, результат создают резервную копию...
Что делает Вас, парни думают? Также Вы видите какое-либо это изменение в Linq к сценарию XML (предполагающий изменение контекста для соответствующего XDocument)?
Аплодисменты Anthony
ОБНОВЛЕНИЕ:
Это - способ, которым я обычно реализовывал бы вещи ранее:
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
}
Это, как Вы парни видите, что он работает или не действительно... С или без репозитория я вижу любое из вышеупомянутого, полностью защищающего бизнес-слой от знания чего-либо об используемых методах/технологии доступа к данным...
Да, есть большая разница.
A DAL (например, Table Data Gateway) - это концепция базы данных. Он отвечает за выдачу запросов к базе данных и возвращает наборы записей.
Хранилище хранилище - это концепция домена. Он отвечает за прием структурированных запросов и возврат сильно типизированных объектов.
Очень разные на практике.
Обновление:
Вопрос, похоже, отражает значительное количество путаницы, поэтому позвольте мне попытаться прояснить ситуацию на примере кода. Вот дизайн, который вы могли бы использовать, если бы вы не использовали никакой 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);
}
Хранилище:
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 имеет дело с данными. Конкретный Repository может инкапсулировать классы доступа к данным, но абстрактный repository (его публичный интерфейс) имеет дело только с классами домена.
Еще раз напомню читателям, что это даже близко не код производственного качества, и что большинство приложений сегодня используют ORM или, по крайней мере, какую-то лучшую форму автоматического отображения. Это только для примера.
Вы, кажется, хорошо с этим справляетесь. «Классы доступа к данным» могут принимать самые разные формы. Это своего рода класс, имеющий отношение к доступу к данным. Ваш Репозиторий является (A) шаблоном для обработки ваших данных и (B) местом в вашей схеме доступа к данным (если вы реализуете репозиторий).
Задача вашей стратегии доступа к данным - обеспечить одновременно гибкость и возможность многократного использования. И в то же время эффективен. В то же время работая со своей бизнес-логикой, будучи разделенным, но также связным . Сложный.
Репозиторий - это шаблон, который призван помочь со всем этим балансом. Ваш код для перевода db (или чего-то еще) в классы сущностей и из них находится в одном месте для каждой сущности. Ваши «классы доступа к данным» могут состоять из классов вашего репозитория, а также классов, которые фактически обрабатывают работу с sql. Вы, конечно же, не должны делать всю работу с sql внутри каждого из ваших классов репозитория.
Пример: вы можете начать использовать неэффективное, но легкое отражение для заполнения ваших объектов сущностей, почти не выполняя никакой работы в ваших классах репозитория; позже вы сможете сделать его более эффективным для объектов большого объема, но это будет полностью скрыто от других частей вашей системы. А потом вы переносите некоторую конфигурацию в XML, но остальная часть вашей системы не знает об этом изменении.
Платформа LINQ-to-sql и Entity действительно использует шаблон репозитория, потому что то, что возвращают классы репозитория, на самом деле является IQuerable этой сущности.Бизнес-классы могут применять дополнительные критерии, и эти критерии фактически попадают в sql, при этом обеспечивая полную инкапсуляцию из сохраняемости данных. Это серьезно круто.