5

データベースへの複数のラウンド トリップのコストを発生させずに、LINQ to SQL クエリとドメイン オブジェクトへのマッピングを DRY にしようとすると問題が発生します。この例を考えると:

var query1 = from x in db.DBProducts
            select new MyProduct
            {
                Id = x.ProductId,
                Name = x.ProductName,
                Details = new MyProductDetail
                {
                    Id = x.DBProductDetail.ProductDetailId,
                    Description = x.DBProductDetail.ProductDetailDescription
                }
            }

クエリは、DB へのラウンド トリップを 1 回行います。すごい!ただし、これに伴う問題は、最終的には、上記と非常によく似た、同じ「データ オブジェクト -> ドメイン オブジェクト」マッピングを実行する必要がある 'GetProductDetails' メソッドも必要になることです。

マッピングの一部を軽減するために、次のように、部分データ オブジェクト クラスを拡張してマッピングを行うのはクールなアイデアかもしれないと考えました。

public partial class DBProduct
{
    MyProduct ToDomainObject()
    {
        return new MyProduct
        {
            Id = this.ProductId,
            Name = this.ProductName,
            Details = this.DBProductDetails.ToDomainObject()
        };
    }
}

public partial class DBProductDetail
{
    MyProductDetail ToDomainObject()
    {
        return new MyProductDetail
        {
            Id = this.ProductDetailId,
            Description = this.ProductDetailDescription
        };
    }
}

良い!これで、query1 を次のように簡単に書き直すことができます。

var query1 = from x in db.DBProducts
            select x.ToDomainObject();

これにより、コードがより DRY になり、読みやすくなります。さらに、同じタイプのマッピングを行う必要がある他のクエリは、マッピングに ToDomainObject() メソッドを使用するだけです。機能しますが、コストがかかります。プロファイラーで監視している間、最初のクエリは db ONCE を呼び出し、必要に応じてテーブルを結合します。2 番目のクエリは適切に結合されないため、DB に対して複数の呼び出しが行われます。私がやろうとしていることを達成する方法はありますか: ドメイン オブジェクトへのマッピングが DRY (コードの重複なし) になるように LINQ to SQL クエリをリファクタリングしますか?

4

1 に答える 1

1

AutoMapperを使用します。一度試してみると、次のようなコードが表示される可能性はほとんどありません。

new MyProduct
{
    Id = x.ProductId,
    Name = x.ProductName,
    Details = new MyProductDetail
    {
        Id = x.DBProductDetail.ProductDetailId,
        Description = x.DBProductDetail.ProductDetailDescription
    }
}
于 2010-03-10T07:34:15.553 に答える