我查询我的数据库并将数据返回给客户端。当我在控制台上记录客户端上的数据时,它按字母顺序排列:
[
[{key='a',val=123},{key='a',val=666},{key='a',val=420}],
[{key='b',val=999},{key='b',val=822},{key='b',val=314}],
[{key='c',val=732},{key='c',val=444},{key='c',val=987}],
]
但是,当我运行我的单元测试时,数据是向后的!
[
[{key='c',val=732},{key='c',val=444},{key='c',val=987}],
[{key='b',val=999},{key='b',val=822},{key='b',val=314}],
[{key='a',val=123},{key='a',val=666},{key='a',val=420}],
]
也许我正在抛出错误的对象?
JsonResult result = (JsonResult)target.GetStockHistory(new string[]{"ABCDEFG", "ZYXWVUT"});
IGrouping<string, StockRecord>[] allStocks = (IGrouping<string, StockRecord>[])result.Data;
我很肯定它在控制台中排序并不是浏览器为我格式化的结果,因为浏览器无法知道要排序的值。它只是解析JSON。
这是我的操作方法(不确定排序或子查询是否导致问题)
public ActionResult GetStockHistory(string[] symbols)
{
StockHistory stocks = new StockHistory();
IEnumerable<StockRecord>[] records = repository.StockRecords
.Where(r => symbols.Contains(r.Symbol))
.GroupBy(r => r.Symbol)
.Select(g =>
g.OrderByDescending(g2 => g2.RecordDate)
.Take(30)
.OrderBy(g3 => g3.RecordDate))
.ToArray();
return Json(records, JsonRequestBehavior.AllowGet);
}
这是测试方法
[TestMethod]
public void Can_Get_Stocks()
{
// arrange
Mock<IStockHistory> mock = new Mock<IStockHistory>();
mock.Setup(m => m.StockRecords).Returns(new StockRecord[] {
new StockRecord {
Symbol = "ABCDEFG",
RecordDate = new DateTime(2000, 1, 1),
LowValue = 1,
HighValue = 10,
AdjustedCloseValue = 8,
CloseValue = 9,
OpenValue = 7,
Volume = 13245
},
new StockRecord {
Symbol = "LMNOP",
RecordDate = new DateTime(2005, 1, 1),
LowValue = 1,
HighValue = 5,
AdjustedCloseValue = 6,
CloseValue = 5,
OpenValue = 4,
Volume = 23456
},
new StockRecord {
Symbol = "ZYXWVUT",
RecordDate = new DateTime(2010, 1, 1),
LowValue = 6,
HighValue = 60,
AdjustedCloseValue = 10,
CloseValue = 10,
OpenValue = 7,
Volume = 67891
}
}.AsQueryable());
CommonController target = new CommonController(mock.Object);
// act
JsonResult result = (JsonResult)target.GetStockHistory(new string[]{"ABCDEFG", "ZYXWVUT"});
IGrouping<string, StockRecord>[] allStocks = (IGrouping<string, StockRecord>[])result.Data;
// allStocks is backwards!?!?! cats and dogs are getting along!
// assert
Assert.AreEqual(2, allStocks.Length);
Assert.AreEqual("ZYXWVUT", allStocks[0].ToArray()[0].Symbol);
Assert.AreEqual("ABCDEFG", allStocks[1].ToArray()[0].Symbol);
Assert.AreEqual(10, allStocks[0].ToArray()[0].CloseValue);
Assert.AreEqual(9, allStocks[1].ToArray()[0].CloseValue);
}
答案 0 :(得分:1)
1.据我所知按密钥库存分组记录应按密钥递减排序。至少你已经设定了你的单元测试期望。但是在你的动作方法查询中,我没有看到按键降序排序。你需要添加它:
IEnumerable<StockRecord>[] records = repository.StockRecords
.Where(r => symbols.Contains(r.Symbol))
.GroupBy(r => r.Symbol)
.OrderByDescending(p => p.Key)
.Select(g => g.OrderByDescending(g2 => g2.RecordDate).Take(30).OrderBy(p => p.RecordDate))
.ToArray();
return Json(records, JsonRequestBehavior.AllowGet);
2.这样的施法IGrouping<string, StockRecord>[] allStocks = (IGrouping<string, StockRecord>[])result.Data
将无法编译。您可以将其替换为IEnumerable<StockRecord>[] allStocks = (IEnumerable<StockRecord>[]) result.Data;
然后它将根据您在单元测试中定义的expcetations行为
答案 1 :(得分:1)
我只是愚蠢。这是一个不同的查询,就是这样排序。这就是我最终的结果:
行动方法
public ActionResult GetStockHistory(string[] symbols, int maxRows = Int32.MaxValue)
{
IEnumerable<IEnumerable<StockRecord>> records;
records = repository.StockRecords
.Where(r => symbols.Contains(r.Symbol))
.GroupBy(r => r.Symbol)
.Select(g => g
.OrderByDescending(g2 => g2.RecordDate)
.Take(maxRows)
.OrderBy(g3 => g3.RecordDate));
return Json(records, JsonRequestBehavior.AllowGet);
}
UNIT TEST
[TestMethod]
public void Can_Get_Stock()
{
// arrange
Mock<IStockHistory> mock = new Mock<IStockHistory>();
mock.Setup(m => m.StockRecords).Returns(new StockRecord[] {
new StockRecord {
Symbol = "ABCDEFG",
RecordDate = new DateTime(2000, 1, 1)
}
}.AsQueryable());
CommonController target = new CommonController(mock.Object);
// act
JsonResult result = (JsonResult)target.GetStockHistory(new string[] { "ABCDEFG" });
IEnumerable<IEnumerable<StockRecord>> allStocks = (IEnumerable<IEnumerable<StockRecord>>)result.Data;
// assert
Assert.AreEqual(1, allStocks.Count());
StockRecord[] record1 = allStocks.ElementAt(0).ToArray();
StockRecord record1_row1 = record1[0];
Assert.AreEqual("ABCDEFG", record1_row1.Symbol);
}
答案 2 :(得分:0)
集合(如SQL SELECT查询)不保证按任何特定顺序排列 - 这意味着可能的结果将被排序。
根据我的经验,任何.To___()
调用都会撤消之前指定的.OrderBy()
方法。因此,当您的代码在 .ToArray()
之后调用.OrderBy(g3 => g3.RecordDate)
时,它会重置任何排序。结果在客户端上排序的事实可能只是一个侥幸。
解决方案是稍后在.ToArray()
链中调用.OrderBy()
,或在转换为数组后再调用.OrderBy()
。