Можно ли попытаться преобразовать деревья выражений между бизнесом и областями данных? - PullRequest
4 голосов
/ 27 августа 2010

У меня есть слой репозитория, который имеет дело с автоматически сгенерированными сущностями LINQ to SQL.В конечном итоге они отображаются на предметно-ориентированные типы на поверхности.Теперь я хотел бы предоставить некоторые более сложные возможности запросов для клиентского кода, и этот клиентский код знает только о типах объектов домена.

Я хотел бы реализовать это с помощью шаблона объекта запроса (как называетсяв паттернах корпоративной архитектуры приложений Мартина Фаулера), но позволяя клиентскому коду использовать лямбда-выражения с типами доменов.Под прикрытием я хотел бы преобразовать лямбда-выражение с учетом домена в лямбду с учетом базы данных и отправить это преобразованное выражение в хранилище для выполнения в базе данных с LINQ to SQL.

В настоящее время у меня естьРеализация бедного человека, которая ограничивает способность отображения клиента простыми свойствами, но я бы хотел немного открыть ее для более сложных запросов.Я не уверен, как бы я подошел к этому с AutoMapper или любым другим существующим инструментом отображения, и я не уверен, ОТКРЫТО, как я мог бы сделать это с доморощенным кодом.

Вот какая функциональность мне бы понравилась:

// Example types to be interconverted...
//    DomainId should map to DataEntityId and vice versa
//    DomainName should map to DataEntityName and vice versa
public class DomainType
{
    public int DomainId { get; set; }
    public string DomainName { get; set; }
}
public class DataEntityType
{
    public int DataEntityId { get; set; }
    public string DataEntityName { get; set; }
}

// And this basic framework for a query object.
public class Query<T>
{
    public Query(Func<T, bool> expression) { ... }
    public Func<T, bool> Query { get; }
}

// And a mapper with knowledge about the interconverted query types
public class QueryMapper<TSource, TDestination> 
{
    public void SupplySomeMappingInstructions(
             Func<TSource, object> source, Func<TDestination, object> dest);
    public Query<TDestination> Map(Query<TSource> query);
}

// And a repository that receives query objects
public class Repository<T> 
{
    public IQueryable<T> GetForQuery(Query<T> query) { ... }
}   

С конечной целью заставить что-то подобное работать:

// a repository that is tied to the LINQ-to-SQL types.
var repository = new Repository<DataEntityType>(...);

// a query object that describes which domain objects it wants to retrieve
var domain_query = new Query<DomainType>(item => item.DomainId == 1);

// some mapping component that knows how to interconvert query types
var query_mapper = new QueryMapper<DomainType, DataEntityType>();
query_mapper.SupplySomeMappingInstructions(
                   domain => domain.DomainId, data => data.DataEntityId);
query_mapper.SupplySomeMappingInstructions(
                   domain => domain.DomainName, data => data.DataEntityName);


IQueryable<DataEntityType> results = 
    repository.GetForQuery(query_mapper.Map(domain_query));

Мои вопросы действительно такие, я думаю:

  1. Возможно ли этосоздать такой картограф, и если это так ...
  2. Возможно ли это сделать с помощью такого инструмента, как AutoMapper, и если это так ...
  3. Можно ли воспользоваться преимуществамиAutoMapper отображает, что у меня уже есть, что преобразует DomainType и DataEntityType или мне нужно было бы явно сопоставить Query<DomainType> с Query<DataEntityType>?

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

Ответы [ 2 ]

1 голос
/ 29 августа 2010

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

Многие люди не знают, что Linq 2 SQL на самом деле поддерживает POCOстиль , хотя бы в какой-то степени?Если вы можете рассмотреть другие альтернативы ORM, то и NHibernate, и Entity Framework имеют лучшую поддержку POCO.

POCO позволяет вам определять модель вашего домена непосредственно поверх ORM, но таким образом, чтобы классы вашего домена могли (более или менее, в зависимости от фактического ORM) оставаться «невежественными».Таким образом, вы можете использовать возможности запросов ORM для предоставления своим пользователям расширенного API запросов к доменам.

Если вы рассмотрите Entity Framework (v4), вам также может понадобиться взглянуть на WCFУслуги передачи данных

Только мои 2 цента ...

0 голосов
/ 28 декабря 2012

Если вы хотите разрешить запросы LINQ, написанные для ViewModels, и выполнить их в репозитории, использующем модели сущностей, вам также необходимо проверить деревья выражений LINQ и перевод дерева выражений.AutoMapper будет полезен при переводе объектов, но ваши деревья выражений также нуждаются в переводе.

http://blogs.msdn.com/b/charlie/archive/2008/01/31/expression-tree-basics.aspx

...