4

Linqは初めてです。私は強く型付けされたデータセットを使用していますが、オブジェクトを作成するためのLinqのアイデアが好きです。

現在、データセットを使用して、tblProductsとtblProductSettingsからデータを結合するテーブルを取得しています。

製品はWebサイトごとに一意のtblSettings行を持つ複数のWebサイトにサービスを提供するため、これは1対多の関係ですが、WebサイトごとにtblSettingsの行が常に1つあると想定されています。

例 :

Select * from tblproducts, tblProductSettings where tblproducts.ProdID = tblProductSettings.ProdID and tblProductSettings.CreatorID = @CreatorID

データセットは、設定を使用して製品をループして表示するための優れたテーブルを提供します。

Linqは、tblProductSettingsをコレクションとして持つtblProductsオブジェクトを提供します。設定を取得するために毎回コレクションをループする必要はありません。製品ごとに新しいSQLクエリを作成し、設定へのアクセスを面倒にすると思います。

カスタムオブジェクトtblProductsAllを作成できますが、このオブジェクトを埋める唯一の方法は...

var Product = from p in context.tblProducts
              join ps in context.tblProductSettings on p.ProdID equals ps.ProdID
              where p.CreatorID == 1 && ps.ProdCreatorDisplay == 1
              select new tblProductsAll() 
              { 
                   ProdTitle = p.ProdTitle,
                   ProdPrice = ps.ProdPrice
              };

次に、このモデルをかみそりのテンプレートに渡すことができます。

私の質問は...プロパティを設定するより良い方法はありますか?20以上の異なるプロパティがあり、同じオブジェクトが異なるwhere句を使用してサイトに存在するたびに、コードを繰り返して設定し続ける必要はありません。この繰り返しを止める方法はありますか?つまり、オブジェクトを自動的にマッピングするか、selectnewステートメントを再利用します。

どんな助けでも大歓迎です。

4

2 に答える 2

0

このにタグを付けたので、EntityFrameworkを使用していると思います。その場合、結合を明示的に指定せずに、製品の設定をロードするようにlinqに指示できます。ここでは、製品が、製品エンティティの設定プロパティを介して公開される製品設定テーブルと関係があると想定しています。

var allProducts = context.tblProducts
    .Where(p => p.CreatorID == 1 && p.Settings.ProdCreatorDisplay == 1)
    .Include(p = p.Settings)
    .Select(p => CreateViewModelFromFullyPopulatedProductModel(p))
    .ToList();

完全な設定をロードしたら、マッピングを行うマッピング関数を作成するだけです。もちろん、これにより、製品のすべてのプロパティとそれらの各製品の設定が読み込まれます。ロードする製品の数と未使用のプロパティの数によっては、これが大きな問題になる可能性がありますが、質問からすると、ビューモデルのこれらの値のほとんどをすでにロードしているようです。

于 2012-11-30T16:24:49.987 に答える
0

ナビゲーションプロパティがある場合は、それらを使用してください。エンティティProductにはナビゲーションプロパティがありますProductSettings。つまり、クエリは次のようになります。

var products = from p in context.Products
               from ps in p.ProductSettings
               where p.CreatorID == 1 && ps.ProdCreatorDisplay == 1
               select new ProductsAll() 
               { 
                    ProdTitle = p.ProdTitle,
                    ProdPrice = ps.FirstOrDefault().ProdPrice
               };

tbl(私は頑固にプレフィックスの使用を拒否していることに注意してください)

しかし、それは反復的なコードの問題に対処するものではありません。

AutoMapperと入力します。これは、オブジェクト間のマッピングを定義して実行することにより、コードから定型プロパティのコピーステートメントを削除する便利な小さなツールです。デフォルトのマッピングは、命名規則に基づいています。たとえば、ステートメントは、とMapper.CreateMap<Product,ProductDto>();のすべての同じ名前のプロパティ間のマッピングを構成します。そして、からオブジェクトを作成します。ProductProductDtoMapper.Map<ProductDto>(product);ProductDtoproduct

しかし、あなたのProductsAllクラスにProdPriceはから来るプロパティがありますProductSettings。どのように対処するのですか?

ここでは、AutoMapperの優れた機能を使用できます。また、命名規則に基づいてネストされたオブジェクトのプロパティを解決します。クラスProductにプロパティがあるとするとTitle、AutoMapperはそれをProductTitleターゲットオブジェクトのプロパティに解決できます。それを使用しましょう:

class ProductsAll
{
    // ProductSetting should have a Product property.
    public string ProductTitle { get; set; }
    // Assuming ProductSetting has a property ProdPrice.
    public decimal ProdPrice { get; set; }
}

...

Mapper.CreateMap<ProductSetting,ProductsAll>(); // ProductSetting!

var q = from ps in context.ProductSettings
        where ps.Product.CreatorID == 1 && ps.ProdCreatorDisplay == 1;

// Now the magic!
var products = q.Project().To<ProductsAll>();

Project()の拡張メソッドIQueryableです。良い点は、SQLステートメントにプロジェクションで使用されるプロパティのみが含まれていることです。ご覧のとおり、マッピングを1回定義し、残りはProject().To()コードで構成を使用できます。

AutoMapperにはまだまだたくさんのことがあります。これはクイックスタートです。

于 2012-12-02T10:16:57.510 に答える