(对不起,标题模糊,不知道该怎么做。)
这是.NET 4.7,EF 6.1。我有两张桌子:一套产品和一套历史价格。我需要编写一些代码,这些代码将获得所有产品的列表及其提供的两个日期(开始和结束)的价格。这本质上是一个报告,看看产品价格在两个日期之间的变化情况,但我只需要开始/结束价格,而不是介于两者之间的所有价格。
我能够想到的唯一方法就是下面的代码。我会运行两次 - 一次是开始日期,一次是结束日期 - 然后我将这两个列表加入到我需要的模型类型的一个列表中。我不能为我的生活弄清楚如何做到这一点。 我应该如何做到这一点?
简化的表格布局:
Product HistoricalPrice
------- ---------------
-Id -Id
-Name -ProductId
-ModifiedAt
-NewPrice
这是我尝试使用的代码。 Product
是对HistoricalPrice
Product
ProductId
的引用,它是该类的一部分,并以var historicalStartPrices = await _context.ProductHistoricalPrices
// need to include the product itself
.Include(p => p.Product)
// only get prices that come before the start date
.Where(p => p.ModifiedAt <= start)
// order from most recent -> oldest by modified date
.OrderByDescending(p => p.ModifiedAt)
// group prices by the product ID
.GroupBy(p => p.ProductId)
// take only the first result for each product ID
.Select(g => g.First())
// enumerate the results
.ToListAsync();
字段引用。我需要在此代码的最终结果中获取产品名称/ ID。
FirstOrDefault
该代码抛出此异常:
NotSupportedException:方法&#39; First&#39;只能用作最终查询操作。考虑使用方法&#39; FirstOrDefault&#39;在这个例子中反而。
如果我切换到Product
,则所有import java.util.Scanner;
import java.util.Arrays;
public class DestinationPlanner {
static Scanner keyboard = new Scanner(System.in);
static int cityDistance, arrivalCity;
static double gasCost, MPG, totalCost;
static String userContinue, userSelection, departCity;
static double [][] cityTable = {
{0, 384, 706, 729, 744, 767, 605, 548, 492, 346},
{384, 0, 399, 628, 437, 473, 291, 714, 390, 244},
{706, 399, 0, 877, 47, 605, 110, 1086, 742, 640},
{729, 628, 877, 0, 914, 384, 825, 395, 259, 406},
{744, 437, 47, 914, 0, 609, 154, 1123, 780, 685},
{767, 473, 605, 384, 609, 0, 563, 708, 367, 420},
{605, 291, 110, 825, 154, 563, 0, 1002, 679, 533},
{548, 714, 1086, 395, 1123, 708, 1002, 0, 344, 469},
{492, 390, 742, 259, 780, 367, 679, 344, 0, 146},
{346, 244, 640, 406, 685, 420, 533, 469, 146, 0},
};
static String [] citySelection = {"Jacksonville, Fl", "Charlotte, NC", "Washington, DC", "Memphis, TN",
"Baltimore, MD", "Louisville, KY", "Richmond, VA", "New Orleans, LA", "Birmingham, AL", "Atlanta, GA"
};
public static void main(String[] args) {
System.out.println("Welcome to the Southeast Destination Planner!"
+ "\nTo help you plan your trip this program will calculate"
+ "\nthe cost to travel between two popular Southeast cities"
+ "\nWill you continue?"
+ "\nEnter 'y' to continiue 'n' to quit");
userContinue = keyboard.nextLine().toLowerCase();
while ((userContinue.equals("y")) & (userContinue.equals("n"))){
userContinue = keyboard.nextLine().toLowerCase();
}
while (userContinue.equals("n")) {
System.out.println("The program will now terminate");
System.exit(0);
}
while (userContinue.equals("y")) {
citySelection();
carInfo();
finalCost();
}
}
private static void citySelection() {
System.out.println("\nGreat, let's start by determining the city you will be departing");
System.out.println("\nPlease choose from the following cities");
System.out.println("[0] Jacksonville, FL");
System.out.println("[1] Charlotte, NC");
System.out.println("[2] Washington, DC");
System.out.println("[3] Memphis, TNA");
System.out.println("[4] Baltimore, MD");
System.out.println("[5] Louisville, KY");
System.out.println("[6] Richmond, VA");
System.out.println("[7] New Orleans, LA");
System.out.println("[8] Birmingham, AL");
System.out.println("[9] Atlanta, GA");
System.out.println("\nWhere will your trip begin?");
departCity = keyboard.nextLine();
while (!(departCity.equals("1")) && !(departCity.equals("2")) && !(departCity.equals("3")) &&
!(departCity.equals("4")) && !(departCity.equals("5")) && !(departCity.equals("6")) &&
!(departCity.equals("7")) && !(departCity.equals("8")) && !(departCity.equals("9")) &&
!(departCity.equals("0"))){
System.out.println("Please enter a number 0 through 9");
departCity = keyboard.nextLine();
}
System.out.println("\nYou have chosen to depart from " + citySelection[departCity]);
}
都为空。
答案 0 :(得分:0)
为什么需要将产品包含在产品历史价格中?这些表格不相关吗? 也许对代码进行简单修改有助于实现目标:
var historicalStartPrices = await _context.ProductHistoricalPrices;
// only get prices that come between start and end dates
.Where(p => p.ModifiedAt >= start && p.ModifiedAt <= end
// order from most recent -> oldest by modified date
.OrderByDescending(p => p.ModifiedAt)
// take only prices foreach products in ProductHistoricalPrices
.Select(g => g.NewPrice)
// enumerate the results
.ToListAsync();
答案 1 :(得分:0)
这可能会在您的代码中的其他位置引用,但是p.Product
引用的是什么?我没有在你的表中看到这样的通用字段。
此外,如果您尝试获取需要在您要查询的字段旁边的ID的第一个结果。
假设第一个查询不是必需的,那么您的查询看起来可能相同:
.Where(p => p.ModifiedAt <= start)
.OrderByDescending(p => p.ModifiedAt)
.GroupBy(p => p.ProductId.First())
.ToListAsync();
如果你真的需要引用另一个表中的一个项目,你可以将该值存储在一个变量中,或者你可以简单地检索你最近的一个条目:`query.Where(p =&gt; p.ModifiedAt
答案 2 :(得分:0)
您的问题的解决方案(每个产品的初始价格和最终价格)是让您的Linq查询如下所示:
var historicalPrices = await _context.ProductHistoricalPrices.Where(x => x.ModifiedAt >= startDate && x.ModifiedAt <= endDate).Select(x => new
{
ProductId = x.ProductId,
ProductName = x.Product.Name,
Price = x.NewPrice,
ModificationDate = x.ModifiedAt
}).GroupBy(x => x.ProductId).Select(x => new
{
ProductName = x.FirstOrDefault().ProductName,
InitialPrice = x.OrderBy(x => x.ModificationDate).FirstOrDefault().Price,
FinalPrice = x.OrderByDescending(x => x.ModificationDate).FirstOrDefault().Price
}).ToListAsync();