我正在尝试构建控制器以检查数据库中是否已经存在实体(StockData),如果不存在,请添加它。否则,不应添加它。但是,我构建的代码总是添加它,我不明白为什么。
我正在尝试构建一个应用程序(ASP.NET Core MVC,使用SQL Server和EF Core),该应用程序从API加载库存数据并将其显示在页面上。在这种情况下,我想避免保存StockData的重复实体,否则我的数据库将在每次调用时不断填充已经存在的数据。
这是我的控制器以及我的Product和StockData类:
{
private readonly ApplicationDbContext dbContext;
public StockController(ApplicationDbContext dbContext)
{
this.dbContext = dbContext;
}
public IActionResult Index()
{
var symbol = "MSFT";
var name = "Microsoft";
Product product;
if(dbContext.Products.Any(p => p.Symbol == symbol))
{
product = dbContext.Products.FirstOrDefault(p => p.Symbol == symbol);
}
else
{
product = new Product
{
Symbol = symbol,
Name = name
};
dbContext.Add(product);
}
dbContext.SaveChanges();
var apiResponse = $"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={symbol}&interval=5min&apikey=APIKEY&datatype=csv".GetStringFromUrl();
var stocks = apiResponse.FromCsv<List<StockData>>().ToList();
product.Data = stocks;
foreach (var stock in product.Data)
{
if(!dbContext.StockData.Any(s => s.Timestamp.Equals(stock.Timestamp) && s.ProductId.Equals(product.ProductId)))
{
dbContext.Add(stock);
}
}
dbContext.SaveChanges();
return View(product);
}
}
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Symbol { get; set; }
public string Description { get; set; }
public List<StockData> Data { get; set; }
}
public class StockData
{
[Ignore]
public int StockDataId { get; set; }
[Ignore]
public int ModelId { get; set; }
[Ignore]
public int ProductId { get; set; }
public string Timestamp { get; set; }
public string Open { get; set; }
public string High { get; set; }
public string Low { get; set; }
public string Close { get; set; }
public string Volume { get; set; }
}
答案 0 :(得分:1)
如果找到ID,这应该更新记录,否则应添加它。
private readonly ApplicationDbContext dbContext;
public StockController(ApplicationDbContext dbContext)
{
this.dbContext = dbContext;
}
public IActionResult Index()
{
var symbol = "MSFT";
var name = "Microsoft";
Product product;
product = dbContext.Products.FirstOrDefault(p => p.Symbol.Equals(symbol));
if (product == null)
{
dbContext.Add(new Product() { Symbol = symbol, Name = name });
}
else
{
dbContext.Entry(product).State = EntityState.Modified;
}
dbContext.SaveChanges();
var apiResponse = $"https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol={symbol}&interval=5min&apikey=APIKEY&datatype=csv".GetStringFromUrl();
var stocks = apiResponse.FromCsv<List<StockData>>().ToList();
product.Data = stocks;
foreach (var stock in product.Data)
{
var newStock = dbContext.StockData.FirstOrDefault(s => s.ProductId.Equals(product.ProductId));
if (!dbContext.StockData.Any(s => s.Timestamp.Equals(stock.Timestamp)))
{
if (newStock == null)
{
dbContext.Add(stock);
}
else
{
dbContext.Entry(stock).State = EntityState.Modified;
}
dbContext.SaveChanges();
}
}
return View(product);
}
答案 1 :(得分:0)
我相信我发现了造成重复问题的原因。
foreach
方法实际上可以很好地工作,禁止根据if
语句的条件向数据库添加新库存。
但是,由于某种原因,product.Data = stocks;
是通过某种方式自动 添加了product.Data
(即从API中新获取的stocks
集合)到数据库,即使没有任何明确的方法也可以。
我不确定为什么会这样,但是我重构了代码以使用临时库存清单(tempStocks
)来避免将整个获取的stocks
集合添加到{{1 }},像这样:
product.Data
可能不是最优雅的解决方案,但我希望它能帮助遇到同样问题的人。