У меня есть слой репозитория, который связан с объектами с автогенерированием LINQ to SQL. В конечном итоге они отображаются на поверхности, удобные для использования на поверхности. Теперь я хотел бы предоставить несколько более сложных запросов для клиентского кода, и этот код клиента знает только о типах объектов домена.Можно ли попытаться преобразовать деревья выражений между доменами бизнеса и данных?
Я хотел бы реализовать это с помощью шаблона объекта запроса (как указано в шаблонах архитектуры корпоративного приложения Мартина Фаулера), но позволяет клиентскому коду использовать лямбда-выражения с типами доменов. Под обложками я хотел бы преобразовать выражение lambda, поддерживающее домен, в lambda с поддержкой базы данных и отправить это преобразованное выражение в репозиторий для выполнения с базой данных с LINQ to SQL.
В настоящее время у меня есть реализация неимущего человека, которая ограничивает способность сопоставления клиента к простым свойствам, но я бы хотел немного открыть его для более сложных запросов. Я не уверен, как я подойду к этому с помощью AutoMapper или любого другого существующего инструмента отображения, и я не уверен OTTOMH, как я мог бы сделать это с помощью домашнего кода.
Вот вид функциональности я хотел бы:
// 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));
Мои вопросы действительно это, я думаю:
- Возможно ли создание такого картографа, и если да, то ...
- ли это возможно сделать это с помощью инструмента, как AutoMapper, и если это так ...
- Можно ли воспользоваться отображением AutoMapper, что у меня уже есть, что interconverts
DomainType
иDataEntityType
или же мне нужно явно отобразитьQuery<DomainType>
вQuery<DataEntityType>
?
Я в конечном счете хочу сделать это, чтобы иметь гибкость при использовании произвольных функций отображения, которые не обязательно являются простыми свойствами объекта.
Смотрите мой ответ на аналогичный вопрос здесь, используя AutoMapper и ExpressionVisitor: http://stackoverflow.com/questions/7424501/automapper-for-funcs-between-selector-types/7425211#7425211 – luksan