1

データベースとそれにマッピングされた Entity Framework モデルがあります。データベースには、多数の列を持つテーブル「Products」があります。多くの EF クエリでは、数列しか必要なく、射影を行います。

var projected = Context.Products
    .Select(p => new ProjectedProduct { ProdID = p.ID, ProdTitle = p.Title })
    .ToArray();

このプロジェクションは何度も使用されるため、別のメソッドに移動します。

public static IQueryable<ProjectedProduct> ToProjectedProduct(this IQueryable<Product> query)
{
    return query.Select(p => 
        new ProjectedProduct { ProdID = p.ID, ProdTitle = p.Title });
}

したがって、次のような投影を使用できます。

var projected = Context.Products.ToProjectedProduct().ToArray();

ここで、次のように、製品の単一のインスタンスにも同じ射影を使用したいと考えています。

var prod = Context.Products.First(p => p);
var projected = new ProjectedProduct { ProdID = prod.ID, ProdTitle = prod.Title });

そして、投影を 1 か所に配置するために同じヘルパー メソッドを使用したいのですが、IQueryable に対してのみ機能するため、機能しません。私ができることは、投影を次のような別の方法に変換することです

public static ProjectedProduct ToProjectedProduct(this Product p)
{
    return new ProjectedProduct { ProdID = p.ID, ProdTitle = p.Title });
}

しかし、この方法は IQueryable では機能しません。両方のケースで機能するヘルパー メソッドが必要です。やりたいことは次のとおりです。

var projected = Context.Products.Select(p => p.ToProjectedProduct()).ToArray();

しかし、ヘルパー メソッドをデータベース クエリに変換できないため、これは機能しません。

4

2 に答える 2

1

これにはAutomapperを使用します。Automapper を使用すると、次のことができます。

Mapper.CreateMap<Product, ProjectedProduct>
    .ForMember(dto => dto.ProdID, m => m.MapFrom(p => p.ID))
    .ForMember(dto => dto.ProdTitle , m => m.MapFrom(p => p.Title));

(ForMemberは、異なる名前のプロパティ間のマッピングを指定します。Automapper は、同じ名前のプロパティを自動的にマップします)。

これで、再利用可能なプロジェクションが定義されました。

後で行うことができます:

var projected = Context.Products.Project().To<ProjectedProduct>().ToArray();

Automapper は広く使用されており、使用方法の例がたくさんあります。

于 2013-04-02T23:05:42.413 に答える
0

IQueryable の select 拡張メソッドには、Expression<Func<TSource, TResult>>. これが意味することは、このパラメーターに一致するオブジェクトを別の場所で定義し、select ステートメントに渡すことができるということです。

プロパティ (メソッドの場合もあります):

public Expression<Func<Product, ProjectedProduct>> MapProduct
{
    get
    {
        return p => new ProjectedProduct { ProdID = p.ID, ProdTitle = p.Title };
    }
}

IQueryable の使用法:

var projected = Context.Products
    .Select(MapProduct)
    .ToArray();

単一インスタンスの使用:

var projected = Context.Products.Select(MapProduct).First();

IEnumerable の使用法:

// calling compile turns the expression into a normal Func
var projected = ProductList.Select(MapProduct.Compile());

通常のオブジェクトの使用法:

var projected = MapProduct.Compile()(ProdObj);

MSDN IQueryable.Select - http://msdn.microsoft.com/en-us/library/bb534638(v=vs.100).aspx

于 2013-04-02T23:15:02.433 に答える