6

必要に応じて「特定の質問」にスキップしてください。いくつかの背景:

シナリオ: DDLが入力された「ドリルダウン」フィルター(クエリオブジェクト)を備えた一連の製品があります。プログレッシブDDLを選択するたびに、製品リストとDDLに残されるオプションがさらに制限されます。たとえば、ツールからハンマーを選択すると、製品サイズがハンマーサイズのみを表示するように制限されます。

現在の設定:クエリオブジェクトを作成してリポジトリに送信し、各オプションをSQLの「テーブル値関数」にフィードしました。null値は「すべての製品を取得」を表します。

これは良い努力だと思いますが、DDDは受け入れられません。SQLでの「プログラミング」を避けたいのですが、できればリポジトリですべてを実行します。このトピックに関するコメントをいただければ幸いです。

具体的な質問:

このクエリを動的クエリとして書き直すにはどうすればよいですか?101 Linq Examplesのようなものへのリンクは素晴らしいでしょうが、動的クエリスコープがあります。オプションのリストが必要な引用符""のフィールドと、そのオプションを持つ製品の数をこのメソッドに渡したいと思います。

from   p in db.Products
group  p by p.ProductSize into g
select new Category { 
       PropertyType = g.Key,
       Count = g.Count() }

各DDLオプションには、「選択(21)」があります。ここで、(21)は、その属性を持つ製品の数量です。オプションを選択すると、残りのすべてのDDLが残りのオプションとカウントで更新されます。

編集:追記:

.OrderBy("it.City") // "it" refers to the entire record
.GroupBy("City", "new(City)") // This produces a unique list of City
.Select("it.Count()") //This gives a list of counts... getting closer
.Select("key") // Selects a list of unique City
.Select("new (key, count() as string)") // +1 to me LOL.  key is a row of group
.GroupBy("new (City, Manufacturer)", "City") // New = list of fields to group by
.GroupBy("City", "new (Manufacturer, Size)") // Second parameter is a projection

Product
.Where("ProductType == @0", "Maps")
.GroupBy("new(City)", "new ( null as string)")// Projection not available later?
.Select("new (key.City, it.count() as string)")// GroupBy new makes key an object

Product
.Where("ProductType == @0", "Maps")
.GroupBy("new(City)", "new ( null as string)")// Projection not available later?
.Select("new (key.City, it as object)")// the it object is the result of GroupBy

var a = Product
        .Where("ProductType == @0", "Maps")
        .GroupBy("@0", "it", "City") // This fails to group Product at all
        .Select("new ( Key, it as Product )"); // "it" is property cast though

私がこれまでに学んだことは、 LinqPadは素晴らしいですが、それでも答えを探しています。最終的には、このような完全にランダムな研究が普及すると思います。笑。

編集:

Jon Skeetは素晴らしいアイデアを持っていました:私が必要なものをキャストしIGrouping<string, Product>ます。ジョンスキートに感謝します!オブジェクトをキャストしたら、セットを列挙して、結果を別のリストにフィードできます。

4

2 に答える 2

4

(上記のように)クエリ構文を使用してこれを行う方法はわかりませんが、メソッド構文を使用すると、以下に示すようにExpression<Func<を使用できます。このサンプルは、AdventureWorks SQL Serverデータベース(Productsテーブル)に対して機能し、文字列を使用してグループ化する列を指定できます(このサンプルではサイズを選択しました)

using System;
using System.Linq;
using System.Linq.Expressions;

namespace LinqResearch
{
    public class Program
    {
        [STAThread]
        static void Main()
        {
            string columnToGroupBy = "Size";

            // generate the dynamic Expression<Func<Product, string>>
            ParameterExpression p = Expression.Parameter(typeof(Product), "p");

            var selector = Expression.Lambda<Func<Product, string>>(
                Expression.Property(p, columnToGroupBy),
                p
            );

            using (LinqDataContext dataContext = new LinqDataContext())
            {
                /* using "selector" caluclated above which is automatically 
                compiled when the query runs */
                var results = dataContext
                    .Products
                    .GroupBy(selector)
                    .Select((group) => new { 
                        Key = group.Key, 
                        Count = group.Count()
                    });

                foreach(var result in results)
                    Console.WriteLine("{0}: {1}", result.Key, result.Count);
            }

            Console.ReadKey();
        }
    }
}
于 2010-04-03T21:02:55.040 に答える
1

C#ビットを見ると、作成者は動的データを使用してカスケードフィルターを作成する方法について説明しています。ダイナミックデータを使用しているようには聞こえませんが、彼はあなたに役立つかもしれない素晴らしい表現ビルダーを持っています。BuildQueryBodyを参照してから、Iqueryableの拡張メソッドの次のセクションを参照してください。

動的データを使用していないため、「MetaForeignKeyColumn」オブジェクトにアクセスできないことに対処する必要がありますが、彼のアプローチがあなたの質問に役立つと思います。

これがお役に立てば幸いです。

于 2010-04-01T14:00:36.543 に答える