我正在尝试创建一个LINQ查询,该查询允许用户从网页上的下拉菜单中选择“最小”或“最大”。如果用户选择“最低”,它将显示报价最低的记录(报价来自名为“租金”的数据库表)
.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; }
}
}
答案 0 :(得分:0)
让我们看下面的示例(Here is your live code)
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; }
}
}
注意:更改option
的值在0、1、2范围内以测试您的情况。
答案 1 :(得分:0)
只要您确定else
中有数据,您在Quote
中的最后一个示例应该可以返回最大值_context.Rentals
。我不确定您为什么使用Async Task
,但是您没有等待UserInput == 1
或else
中的任何事物,仅等待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;
}
}
答案 2 :(得分: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
分组以获得最大/最小Quote
,然后获得包含那些RentalID
和Quote
的第一条记录。
如果它们具有相同的引用,并且您想显示所有记录而不是第一条记录:
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();
答案 3 :(得分:0)
正如其他人所提到的,您需要使用.Select(s => s.Quote).Min()
(或.Max
)。但是,您的select
列表选项没有任何值。您需要指定适当的值,例如:
<option value="0">All</option>
<option value="1">Min</option>
<option value="2">Max</option>
答案 4 :(得分:0)
我认为部分问题是您仅在Rental
的情况下分配UserInput == 0
。在其他情况下,添加作业将使您的结果在用户更改输入时更新。
另外,听起来您想获取具有最大(或最小)Quote
的所有对象的完整记录。如果是这种情况,那么OrderBy
和GroupBy
方法应该会有所帮助,因为它们使您可以根据数据的属性(例如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
}
}