F # LINQ Совокупная разница в кодах операторов - PullRequest
0 голосов
/ 01 февраля 2012

Я изучаю LINQ в F # 3.0, попробуйте использовать некоторые примеры в Интернете.
Один пример, который я нашел, был примером LINQ для операторов C # - LINQ Aggregate.
Этот образец использует Макс, чтобы получить самую дорогую цену среди продуктов каждой категории.

Следующий код находится в C #:

public void Linq87()
{
  List<Product> products = GetProductList();

  var categories =
    from p in products
    group p by p.Category into g
    select new { Category = g.Key, MostExpensivePrice = g.Max(p => p.UnitPrice) };

  ObjectDumper.Write(categories);
}

Результат:

Category=Beverages
Category=Condiments
Category=Produce
Category=Meat/Poultry
Category=Seafood
Category=Dairy Products
Category=Confections
Category=Grains/Cereals     
MostExpensivePrice=263.5000
MostExpensivePrice=43.9000
MostExpensivePrice=53.0000
MostExpensivePrice=123.7900
MostExpensivePrice=62.5000
MostExpensivePrice=55.0000
MostExpensivePrice=81.0000
MostExpensivePrice=38.0000

Однако в F # синтаксис совершенно другой.
В F # я пробовал что-то вроде этого:

let expensiveProducts =
    query {
          for p in products do
          groupValBy p.Category into g
          select ( g )
          }

Но я не понимаю результата.
Синтаксис C # для LINQ: «выбрать новый» не работает в F #.
Кто-нибудь может понять это?
Я считаю, что код в C # и F # должен быть не совсем другим, но я не знаю.

Ответы [ 2 ]

4 голосов
/ 02 февраля 2012

Ваш groupValBy оператор неверен .Для группировки необходимо указать значение (p) и ключ (p.Category).

Нет такой вещи, как анонимный тип C # в F #;простой альтернативой является использование кортежей:

let expensiveProducts =
    query {
          for p in products do
          groupValBy p p.Category into g // groupByVal has two arguments here
          select (g.Key, g.Max(fun (p: Product) -> p.UnitPrice))
          }

Если вы хотите, чтобы в результатах были явные имена полей, лучше всего объявить тип записи:

// MostExpensivePrice is nullable due to the return type of g.Max
type Result = { Category: string; MostExpensivePrice: Nullable<int> }

и *Оператор 1014 * должен выглядеть так:

select { Category = g.Key; 
         MostExpensivePrice = g.Max(fun (p: Product) -> p.UnitPrice) }
0 голосов
/ 07 февраля 2012

Наконец, я понял это. Позвольте мне использовать пример базы данных: AdventureWorksLT, для таблицы SalesLT.Product. Я могу использовать следующий оператор SQL для получения некоторых значений Max (*):
ВЫБЕРИТЕ ProductCategoryID, МАКС. (ListPrice) AS Max_Prix ОТ ПРОДАЖИ.

Ниже приведены результаты из SQL Server 2008 R2 Management Studio:

ProductCategoryID    Max_Prix
5          3399.99
6          3578.27
7          2384.07
8          120.27
9          121.49
10          106.50
11          20.24
12          404.99
13          121.46
14          229.49
15          124.73
16          1364.50
17          80.99
18          1431.50
19          52.64
20          1003.91
21          357.06
22          89.99
23          8.99
24          37.99
25          53.99
26          69.99
27          9.50
28          74.99
29          63.50
30          120.00
31          159.00
32          9.99
33          7.95
34          21.98
35          34.99
36          54.99
37          44.99
38          25.00
39          125.00
40          24.99
41          35.00

Вот мой код на F #, выполняющий ту же работу:

#light
open Microsoft.FSharp.Data.TypeProviders
open Microsoft.FSharp.Linq
open System
open System.Data
open System.Data.Linq
open System.Linq

[<Literal>]
let connString = "Data Source=.;Initial Catalog=AdventureWorksLT;Integrated Security=True"
[<Generate>] 
type dbSchema = SqlDataConnection<connString>
let db = dbSchema.GetDataContext() 

let expensiveProducts =
    query {
          for p in db.SalesLT_Product do
          groupValBy p.ListPrice p.ProductCategoryID into g
          let maxPrice = query { for mp in g do
                                 maxBy mp }
          select (g.Key, maxPrice)
          }
          |> Seq.toArray

let showExpensiveProducts = expensiveProducts
printfn "%A" showExpensiveProducts
printfn "OK"

Результат является следующим:

[|(5, 3399.9900M); (6, 3578.2700M); (7, 2384.0700M); 
  (8, 120.2700M); (9, 121.4900M); (10, 106.5000M); 
  (11, 20.2400M); (12, 404.9900M); (13, 121.4600M); 
  (14, 229.4900M); (15, 124.7300M); (16, 1364.5000M);
  (17, 80.9900M); (18, 1431.5000M); (19, 52.6400M); 
  (20, 1003.9100M); (21, 357.0600M); (22, 89.9900M); 
  (23, 8.9900M); (24, 37.9900M); (25, 53.9900M);
  (26, 69.9900M); (27, 9.5000M); (28, 74.9900M); 
  (29, 63.5000M); (30, 120.0000M); (31, 159.0000M); 
  (32, 9.9900M); (33, 7.9500M); (34, 21.9800M); 
  (35, 34.9900M); (36, 54.9900M); (37, 44.9900M); 
  (38, 25.0000M); (39, 125.0000M); (40, 24.9900M); 
  (41, 35.0000M)|]

Спасибо всем за помощь! Хорошего дня! John

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...