代码之家  ›  专栏  ›  技术社区  ›  Chris Farmer Marcelo Cantos

尝试在业务域和数据域之间转换表达式树是否可行?

  •  4
  • Chris Farmer Marcelo Cantos  · 技术社区  · 14 年前

    我有一个存储库层,它处理linqtosql自动生成的实体。这些最终被映射到表面上的领域友好类型中。我现在想为客户机代码提供一些更复杂的查询功能,客户机代码只知道域对象类型。

    我目前有一个穷人的实现,它将客户机的映射能力限制为简单的属性,但我希望将其打开一点,以实现更复杂的查询。我不确定如何使用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 回复  |  直到 12 年前
        1
  •  1
  •   jeroenh    14 年前

    IMHO,这个设计看起来很复杂。您是否研究过直接通过ORM定义域类型的可能性?这就是ORM的设计目的,毕竟。。。如果不付出巨大的额外努力,它肯定会打开很多可能性。。。

    很多人不知道linq2sql实际上支持 POCO style ,至少在某种程度上?如果您可以考虑其他ORM替代方案,那么NHibernate和entityframework都有更好的POCO支持。

    POCO允许您直接在ORM之上定义域模型,但是您的域类可以(或多或少地,取决于实际的ORM)“持久性无知”。因此,您可以利用ORM的查询功能向用户公开一个丰富的域查询API。

    WCF Data Services

    就我的2分钱。。。