簡體   English   中英

使用 LINQ 查找最小值和最大值

[英]Finding Min and Max using LINQ

我正在嘗試創建一個 LINQ 查詢,允許用戶從我網頁上的下拉列表中選擇“最小值”或“最大值”。 如果用戶選擇 Min 它將顯示具有最低報價的記錄(報價來自名為 rentals 的數據庫表)

我對 .Min() 和 .Max() 沒有任何好感。 我不確定如何解決這個問題,因此我們將不勝感激。

這是我的 if 語句,用於確定用戶在下拉框中選擇的選項:

namespace CarGarageSales.Pages.Queries
{
    [BindProperties]
    public class Query3Model : PageModel
    {
        private readonly CarGarageSales.Data.CarGarageSalesContext _context;

        public IList<Rental> Rental { get; set; }

        [BindProperty(SupportsGet = true)]

        public int UserInput { get; set; }

        public Query3Model(CarGarageSales.Data.CarGarageSalesContext context)
        {
            _context = context;
        }

        public async Task OnGetAsync()
        {

            if (UserInput == 0)
            {
                var Rentals = (from s in _context.Rentals
                               select s);

                Rental = await Rentals.ToListAsync();
            }
            else if (UserInput == 1)
            {
                var Rentals = (from s in _context.Rentals
                               select s).Min();

            }
            else
            {
                var Rentals = (from s in _context.Rentals
                               select s.Quote).Max();
            }
        }
    }
}

這是我的 HTML 部分:

@page
@model CarGarageSales.Pages.Queries.Query3Model
@{
    ViewData["Title"] = "Query3";
}

<h2>Query3</h2>


<form>
    <p>
        Min or Max?:<select asp-for="UserInput">
       <option></option>    
       <option>Min</option>
       <option>Max</option>
    </select>

        <input type="submit" value="Search" />
    </p>
</form>


<p class="Text">Here is the record for the Rentals you requested!</p>

<table class="table Text">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Rental[0].RentalID)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Rental[0].Price)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Rental[0].Duration)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Rental[0].Quote)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Rental)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.RentalID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Price)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Duration)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Quote)
                </td>
            </tr>
        }
    </tbody>
</table>

出租類:

namespace CarGarageSales.Models
{
    [BindProperties]
    public class Rental
    {
        [Required]
        public int RentalID { get; set; }

        [Required]
        [Display(Name = "Price")]
        [Range(100, 200000, ErrorMessage = "Price must be between 100 and 200,000 Pounds")]
        public decimal Price { get; set; }

        [Required]
        [Display(Name = "Duration")]
        [Range(1, 36,ErrorMessage = "Duration must be between 1 and 36 Months")]
        public int Duration { get; set; }

        [Required]
        [Display(Name = "Quote")]
        [Range(20, 10000, ErrorMessage = "Quote must be between 20 and 10000 Pounds")]
        public decimal Quote { get; set; }

        public Customer Customer { get; set; }

        public virtual IList<Car> Cars { get; set; }
        public virtual IList<SalesManRental> SalesManRental { get; set; }
    }
}

讓我們看下面的示例(這是您的實時代碼

using System;
using System.Linq;

public class Program
{
    public static void Main()
    {
        var option = 1;
        var list = new[]{ new Rental{ RentalID = 1,  Quote = 1 }, new Rental{ RentalID = 2,  Quote = 2 }, new Rental{ RentalID = 3,  Quote = 3 }, new Rental{ RentalID = 4,  Quote = 1 }, new Rental{ RentalID = 5,  Quote = 3 } };

        var minQuote = list.Min((p => p.Quote));        
        var maxQuote = list.Max((p => p.Quote));
        var result = list.Where(p => (option == 1 && p.Quote == minQuote) || (option == 2 && p.Quote == maxQuote));
        if(option == 0)
            result = list; 

        foreach(var item in result)
                Console.WriteLine(item.Quote);
    }


    public class Rental
    {
        public int RentalID { get; set; }

        public decimal Price { get; set; }

        public decimal Quote { get; set; }
    }
}

注意:在 0、1、2 范圍內更改option值以測試您的案例。

只要您確定_context.Rentals中有數據,您在else中的最后一個示例應該可以返回 max Quote 我不確定你為什么使用Async Task但你沒有等待UserInput == 1else中的任何內容,只有UserInput == 0

這應該工作

var Rentals = (from s in _context.Rentals select s.Quote).Max();

示例(在此處測試https://dotnetfiddle.net/2SnPcS

using System;
using System.Collections.Generic;
using System.Linq;

public class Program {
    public class Rental
    {
        public int RentalID { get; set; }
        public decimal Price { get; set; }
        public int Duration { get; set; }
        public decimal Quote { get; set; }
    }

    public static void Main()
    {
        // sample data
        var rentals = new List<Rental> {
            new Rental { RentalID = 1, Price = 100.00m, Duration = 2, Quote = 200.00m },
            new Rental { RentalID = 2, Price = 100.00m, Duration = 2, Quote = 200.00m },
            new Rental { RentalID = 3, Price = 100.00m, Duration = 1, Quote = 100.00m },
            new Rental { RentalID = 4, Price = 100.00m, Duration = 1, Quote = 100.00m },
            new Rental { RentalID = 5, Price = 100.00m, Duration = 5, Quote = 500.00m }
        };

        // get min quote
        var minQuote = (from s in rentals select s.Quote).Min();

        // get max quote
        var maxQuote = (from s in rentals select s.Quote).Max();

        Console.WriteLine(string.Format("min={0} max={1}", minQuote, maxQuote));

        // Outputs: min=100.00 max=500.00
    }
}

我不確定您的應用程序的其余部分是什么樣子或它是如何使用的,但是是的,您可以隨意調用您的方法。 您只想要Quote十進制值,還是與之關聯的整個Rental 要根據您向我們展示的內容更改您的OnGetAsync方法,僅獲取十進制值,它看起來像這樣(您幾乎就在那里)。

public decimal GetQuoteAmount()
{
    // this could be min
    if (UserInput == 0)
    {
        return (from s in _context.Rentals select s.Quote).Min();
    }

    // this could be max
    else if (UserInput == 1)
    {
        return (from s in _context.Rentals select s.Quote).Max();
    }
    else 
    {
        // is there a third option? What do you want to happen if they do not select Min or Max?
        return 0;
    }
}

未經測試,但你可以這樣做:

        var filteredRentals = _context.Rentals.GroupBy(g => g.RentalID)
            .Select(x => new Rental
            {
                RentalID = x.Key,
                Quote = x.Max(z => z.Quote),
                Duration = x.FirstOrDefault(r => r.RentalID == x.Key && r.Quote == x.Max(z => z.Quote)).Duration,
                Price = x.FirstOrDefault(r => r.RentalID == x.Key && r.Quote == x.Max(z => z.Quote)).Price
            }).ToList();

這個想法是您按RentalID對其進行分組以獲得 Max/Min Quote ,然后獲取具有這些RentalIDQuote的第一條記錄

如果他們有相同的報價並且您想顯示所有記錄而不是第一個:

        var groupedRentals = _context.Rentals.GroupBy(g => g.RentalID)
            .Select(x => new
            {
                RentalID = x.Key,
                Quote = x.Max(z => z.Quote)
            }).ToList();

        var filteredGroupedRentals = _context.Rentals.Where(r => groupedRentals.Any(g =>
            g.RentalID == r.RentalID &&
            g.Quote == r.Quote))
            .ToList();

正如其他人提到的,您需要使用.Select(s => s.Quote).Min() (或.Max )。 但是,您的select列表選項沒有任何值。 您需要指定適當的值,例如:

<option value="0">All</option>
<option value="1">Min</option>
<option value="2">Max</option>

我認為部分問題在於您僅在UserInput == 0的情況下分配Rental 在其他情況下添加分配應該使您的結果在用戶更改輸入時更新。

此外,聽起來您想獲取所有具有最大(或最小) Quote的對象的完整記錄。 如果是這種情況,那么OrderByGroupBy方法應該在這里有所幫助,因為它們允許您根據數據的屬性對數據進行排序,例如Quote的值,並將具有相同值的數據分組在一起。

例如:

public async Task OnGetAsync()
{
    if (UserInput == 0)
    {
        Rental = _context.Rentals().ToListAsync();
    }
    else if (UserInput == 1)
    {
        // Get the group of items with min quote    
        Rental = _context.Rentals()
            .GroupBy(r => r.Quote) // Group items with the same quote (Quote becomes the Key)
            .OrderBy(g => g.Key)   // Order the groups by quote (smallest will be first)
            .FirstOrDefault()      // Choose the first group (those with min quote)
            .ToListAsync();        // Select the items into a list
    }
    else
    {
        // Get the group of items with max quote    
        Rental = _context.Rentals()
            .GroupBy(r => r.Quote) // Group items with the same quote (Quote becomes the Key)
            .OrderBy(g => g.Key)   // Order the groups by quote (smallest will be first)
            .LastOrDefault()       // Choose the last group (those with max quote)
            .ToListAsync();        // Select the items into a list
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM