8

次のクエリをLINQ構文に変換したいと思います。私はそれを機能させるために管理するのに非常に苦労しています。実際にLINQから始めてみましたが、逆に書いた方が運が良かったかもしれません。

SELECT
    pmt.guid,
    pmt.sku,
    pmt.name,
    opt.color,
    opt.size,
    SUM(opt.qty) AS qtySold,
    SUM(opt.qty * opt.itemprice) AS totalSales,
    COUNT(omt.guid) AS betweenOrders
FROM
    products_mainTable pmt 
        LEFT OUTER JOIN 
            orders_productsTable opt ON opt.products_mainTableGUID = pmt.guid
            LEFT OUTER JOIN orders_mainTable omt ON omt.guid = opt.orders_mainTableGUID AND
                (omt.flags & 1) = 1
GROUP BY
    pmt.sku, opt.color, opt.size, pmt.guid, pmt.name
ORDER BY
    pmt.sku

最終結果は、上記のように製品に関する情報を示す表になります。理解構文を使用して、このクエリをLINQ形式で作成するにはどうすればよいですか?

さらに、フィルターを追加したい場合があります(たとえば、orders_mainTableに)。

これは私が仕事をしようとした一例であり、かなり近いものでしたが、それが「正しい」方法であるかどうかはわかりません。また、orders_productsTableからサイズと色でグループ化できませんでした。

from pmt in products_mainTable
let Purchases = 
        from opt in pmt.orders_productsTable
        where ((opt.orders_mainTable.flags & 1) == 1)
        where ((opt.orders_mainTable.date_completedon > Convert.ToDateTime("01/01/2009 00:00:00")))
        select opt
orderby pmt.sku
select new {
    pmt.guid,
    pmt.sku,
    pmt.name,
    pmt.price,  
    AvgPerOrder = Purchases.Average(p => p.qty).GetValueOrDefault(0),
    QtySold = Purchases.Sum(p => p.qty).GetValueOrDefault(),
    SoldFor = Purchases.Sum(p => p.itemprice * p.qty).GetValueOrDefault()           
}

*編集:

私がやろうとしていることを理解できるようにもう少し明確にするために、ここにもう少し説明があります。

製品はproducts_mainTableに保存されます注文はorders_mainTableに保存されます注文された製品はorders_productsTableに保存されます

製品や注文などに基づいていくつかのレポートを作成し、データを掘り下げて、エンドユーザーに表示する意味のあるビットを見つけたいと思います。

この例では、ある期間に購入された製品のうち、最も人気のある製品を表示しようとしています。販売数、価格、注文あたりのブレイクアウトはどれくらいですか。おそらく最良の順序ではないかもしれませんが、私はただ実験してこれを選びました。

すべてのテーブルは他のテーブルと関係があります。したがって、製品テーブルから、その製品を注文した注文などを知ることができます。

私が抱えている最大の問題は、LINQがどのように機能するか、特にグループ化、集合体データ、拡張機能、サブクエリなどでどのように機能するかを理解することです。楽しかったですが、これを行う方法の詳細な説明を見つけるのが難しいため、イライラし始めています。

4

3 に答える 3

5

私はLINQの初心者でもあります。これが複数のフィールドでグループ化する正しい方法かどうかはわかりませんが、これらのグループ化フィールドを代表キーに変換する必要があると思います。したがって、すべてのグループ化フィールドが文字列または整数であると仮定すると、次のようにキーを作成できます。

        var qry = from pmt in products_mainTable
                  join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID
                  join omt in orders_mainTable on opt.orders_mainTableGUID equals omt.guid
                  where (opt.orders_mainTable.flags & 1) == 1
                  group omt by pmt.sku + opt.price + opt.size + pmt.guid + pmt.name into g
                  orderby g.sku
                  select new
                  {
                      g.FirstOrDefault().guid,
                      g.FirstOrDefault().sku,
                      g.FirstOrDefault().name,
                      g.FirstOrDefault().color,
                      g.FirstOrDefault().price,
                      AvgPerOrder = g.Average(p => p.qty).GetValueOrDefault(0),
                      QtySold = g.Sum(p => p.qty).GetValueOrDefault(),
                      SoldFor = g.Sum(p => p.itemprice * p.qty).GetValueOrDefault()
                  };

私はこれをテストしていないので、これが何らかの形で役立つかどうかを確認してください。

于 2009-02-04T21:44:59.773 に答える
3

ブルーノ、ご協力ありがとうございました!FirstOrDefault() はおそらく最大の助けでした。あなたがしたことのいくつかと別のリソースに従って、私は美しく機能するように見える次のことを思いつきました! 以下のこの LINQ クエリは、上で投稿した SQL のほぼ正確な複製を提供してくれました。

LINQ で LEFT OUTER JOIN を実行する際に見つけた他のリソースは次のとおりです。ブログ投稿

最終的な答え:

 from pmt in products_mainTable
    join opt in orders_productsTable on pmt.guid equals opt.products_mainTableGUID into tempProducts
    from orderedProducts in tempProducts.DefaultIfEmpty()
    join omt in orders_mainTable on orderedProducts.orders_mainTableGUID equals omt.guid into tempOrders
    from ordersMain in tempOrders.DefaultIfEmpty()
    group pmt by new { pmt.sku, orderedProducts.color, orderedProducts.size } into g
    orderby g.FirstOrDefault().sku
    select new {
        g.FirstOrDefault().guid,
        g.Key.sku,
        g.Key.size, 
        QTY = g.FirstOrDefault().orders_productsTable.Sum(c => c.qty),
        SUM = g.FirstOrDefault().orders_productsTable.Sum(c => c.itemprice * c.qty),
        AVG = g.FirstOrDefault().orders_productsTable.Average(c => c.itemprice * c.qty),
        Some = g.FirstOrDefault().orders_productsTable.Average(p => p.qty).GetValueOrDefault(0),
    }
于 2009-02-05T04:32:25.223 に答える
0

これは私にとって非常に役に立ちました。同様の問題を解決しようとしていたのですが、結合がなかったため、ケースがはるかに単純になりました。私は単に 1 つのフィールドをグループ化し、別のフィールドの最小値とカウントを取得しようとしていました。(同じクエリ内の min と count)

Linq 構文で再作成したい SQL は次のとおりです。

select t.Field1, min(t.Field2), COUNT(*)
from SomeTable t
group by t.Field1
order by t.Field1

あなたの投稿のおかげで、私は最終的にこれを思い付くことができました:

from t in SomeTable
group t by new { t.Field1 } into g
orderby g.Key.Field1
select new
{ 
  g.Key.Field1,
  code = g.Min(c => c.Field2),
  qty = g.Count()
}

これにより、バックグラウンドで次の SQL が作成されます。

SELECT [t1].[Field1], [t1].[value] AS [code], [t1].[value2] AS [qty]
FROM (
    SELECT MIN([t0].[Field2]) AS [value], COUNT(*) AS [value2], [t0].[Field1]
    FROM [SomeTable] AS [t0]
    GROUP BY [t0].[Field1]
    ) AS [t1]
ORDER BY [t1].[Field1]

完璧です。まさに私がやりたかったことです。私にとって重要だったのは、新しい {} 内でこれを行うことが可能であることをあなたが示してくれたということでした。これは非常に大きなことです。今後の理解が大幅に深まったと感じています。

于 2009-05-01T15:37:35.990 に答える