4

LINQtoSQL自動生成エンティティを処理するリポジトリレイヤーがあります。これらは最終的に、表面上でドメインに適したタイプにマッピングされます。ここで、クライアントコードにさらに高度なクエリ機能を提供したいと思います。そのクライアントコードは、ドメインオブジェクトタイプについてのみ認識しています。

これをクエリオブジェクトパターン(Martin Fowlerのエンタープライズアプリケーションアーキテクチャのパターンで名前が付けられている)で実装したいのですが、クライアントコードがドメインタイプでラムダ式を使用できるようにします。裏で、ドメイン対応のラムダ式をデータベース対応のラムダに変換し、この変換された式をリポジトリに送信して、LINQtoSQLを使用してデータベースに対して実行したいと思います。

私は現在、クライアントのマッピング機能を単純なプロパティに制限する貧乏人の実装を持っていますが、それをもう少し洗練されたクエリに開放したいと思います。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));

私の質問は本当にこれだと思います:

  1. そのようなマッパーを作成することは可能ですか?もしそうなら...
  2. AutoMapperのようなツールでそうすることは可能ですか?もしそうなら...
  3. すでに相互変換されているAutoMapperマッピングを利用することは可能ですかDomainTypeDataEntityTypeまたは明示的にマッピングQuery<DomainType>する必要がありQuery<DataEntityType>ますか?

最終的には、必ずしも単純なオブジェクトプロパティではない任意のマッピング関数を柔軟に使用できるようにするためにこれを実行したいと思います。

4

2 に答える 2

1

私見ですが、このデザインはかなり複雑に見えます。ORM を介してドメイン タイプを直接定義する可能性を調査しましたか? 結局のところ、ORM はそのために設計されたものです...この巨大な余分な努力をしなくても、確かに多くの可能性が開かれます...

多くの人は、Linq 2 SQL が実際にPOCO スタイルをサポートしていることを、少なくともある程度は知りません。他の ORM の代替案を検討できる場合は、NHibernate と Entity Framework の両方がより優れた POCO サポートを備えています。

POCO を使用すると、ドメイン モデルを ORM の上に直接定義できますが、ドメイン クラスを (実際の ORM に応じて多かれ少なかれ) '永続性を無視' することができます。そのため、ORM のクエリ機能を利用して、豊富なドメイン クエリ API をユーザーに公開できます。

Entity Framework (v4) を検討する場合は、WCF Data Servicesも参照してください。

ちょうど私の2セント...

于 2010-08-28T22:09:42.667 に答える
0

ViewModel に対して記述された LINQ クエリを許可し、エンティティ モデルを使用するリポジトリで実行する場合は、LINQ 式ツリーと式ツリーの変換もチェックアウトする必要があります。AutoMapper はオブジェクトを変換するときに役立ちますが、式ツリーも変換する必要があります。

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

于 2012-12-28T09:43:04.580 に答える