c# - ASP.NET MVC 在单个 HTTP 发布请求中更新主从记录
问题描述
我正在自学 C# 和 MVC,但有 SQL 背景。在单个操作中更新现有的主从记录集(例如客户订单和订单详细信息)时,更新主记录没有问题。关于详细记录,我看到的示例只是删除所有现有详细信息,然后将它们重新添加,而不是仅添加、删除或更新已更改的内容。这看起来简单有效,但涉及对数据库记录的不必要更改,并且可能是复杂关系中的一个问题。
我尝试编写代码来检查现有值与发布的值,以确定每个细节的正确实体状态(添加、删除、修改、未更改)。使用 LINQ except 和 Intersect 来完成这个工作,但似乎会导致意外的性能下降。
(相反,我可以将原始值加载到原始 GET 请求中的“oldValue”隐藏字段中,以与 POST 值进行比较,除非这在多用户环境中不可靠并且似乎是个坏主意。)
我很乐意提供代码示例,但我的问题更多是关于最佳实践。是否有更新现有主从记录集的首选方法?
编辑:我在回答问题时添加了下面的代码。在此示例中,我们的应用程序允许将附加属性附加到产品,并保存在单独的表 ProductAttributes 中。该视图允许用户在同一网页上编辑产品和属性并同时保存。该代码运行良好,但在 SaveChanges 上似乎很慢并且滞后。
public ActionResult Edit(Product product)
{
if (ModelState.IsValid)
{
db.Entry(product).State = EntityState.Modified;
// Establish entity states for product attributes.
List<ProductAttribute> existingAttributes = new List<ProductAttribute>();
existingAttributes = db.ProductAttributes.AsNoTracking()
.Where(x => x.Sku == product.Sku).ToList();
// Review each attribute that DID NOT previously exist.
foreach (ProductAttribute pa in product.ProductAttributes
.Except(existingAttributes, new ProductAttributeComparer()))
{
if (pa.Value is null)
{
// Value didn't exist and still doesn't.
db.Entry(pa).State = EntityState.Unchanged;
}
else
{
// New value exists that didn't before.
db.Entry(pa).State = EntityState.Added;
}
}
// Review each attribute that DID previously exist.
foreach (ProductAttribute pa in product.ProductAttributes
.Intersect(existingAttributes, new ProductAttributeComparer()))
{
if (pa.Value is null)
{
// Value existed and has been cleared.
db.Entry(pa).State = EntityState.Deleted;
}
else
{
if (pa.Value != existingAttributes
.FirstOrDefault(x => x.Attribute == pa.Attribute).Value)
{
// Value has been altered.
db.Entry(pa).State = EntityState.Modified;
}
else
{
// Value has not been altered.
db.Entry(pa).State = EntityState.Unchanged;
}
}
}
db.SaveChanges();
return RedirectToAction("Details", new { id = product.ProductId });
}
return View(product);
}
internal class ProductAttributeComparer : IEqualityComparer<ProductAttribute>
{
public bool Equals(ProductAttribute x, ProductAttribute y)
{
if (string.Equals(x.Attribute, y.Attribute,
StringComparison.OrdinalIgnoreCase))
{
return true;
}
return false;
}
public int GetHashCode(ProductAttribute obj)
{
return obj.Attribute.GetHashCode();
}
}
}
解决方案
推荐阅读
- php - 添加域时,我无法在项目中注册/添加新用户,但它正在本地主机上运行
- angular - 订阅 LoggedIn Observable 不起作用
- java - 如何总结反射数和原始数?
- allennlp - Allennlp 命令或 token_embedders 中没有 Fine-Tune/ Bert_token_embedder 模块
- javascript - Chrome 的“Aw,Snap!错误代码:11”指的是什么?
- snowflake-cloud-data-platform - Snowflake 是否监控“Snowflake Ideas Pages”并采取行动?
- php - 有没有办法根据数据库中的数据只执行 WHERE 语句的一部分?
- c - 从子进程获取退出代码
- python - Colab 没有使用 GPU 进行训练
- operationalerror - django中的操作错误