gpt4 book ai didi

c# - 确保另一条记录不包含字段的相同值

转载 作者:行者123 更新时间:2023-11-30 23:21:18 25 4
gpt4 key购买 nike

我正在使用 C# MVC 为我自己的学术目的构建一个小型内容管理系统。

我有创建页面的功能(列出页面、删除页面等)

在基本层面上,我使用 ID 来验证所有页面都是唯一的。但是当我使用 MVC 时,页面本质上是一个 View - 它可以包含 Razor 。所有这一切都没有问题。

但是我的 ViewName 也必须是唯一的(数据库中不能有两个同名的 View )。此外,我的 ViewPath 必须是唯一的(你不能有两条相同的路线)。

在我的创建页面中,我进行了检查(所有工作)以确保创建一个具有唯一 ID 的新 View ,并且它在创建 View 之前检查 ViewName 和 ViewPath 是否都是唯一的,如果不是则返回相关错误。

所有这些都有效。

现在当我去编辑 View 时。用户可以选择更改 ViewName 和 ViewPath。所以我们需要确保它不会更改为已经存在的 ViewName 和 ViewPath。然而,当我们编辑 View 时, View 本身已经存在,所以我们会收到这些错误信息。

所以我们需要检查我们是否保存到同一个页面,所以我们在 ViewName 的 DB 中查找记录的 id 与当前的 ViewName(因为 ViewNames 是唯一的,所以我们可以得到 ID),并且验证我们确实保存到相同的 View 。然后我们可以使用此检查来确保我们不会显示上述错误,因为我们只是更改 View 的名称并且它不匹配任何现有 View 。

问题是当我点击这条线时出现以下错误

db.Entry(view).State = EntityState.Modified;

错误是:

Additional information: Attaching an entity of type 'xxx' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.

问题:我不知道我的解决方案是否过于复杂,如果是这样,有人可以通过示例建议更好的解决方案。

如果这是正确的“方式”,但我只是以某种方式实现错误,有人可以告诉我如何解决它。

下面是我遇到问题的编辑 Controller 操作的 POST 方法:

public ActionResult Edit([Bind(Include = "Id,ViewName,ViewPath,ViewContent")] View view)
{
View sameView1 = db.View.First(v => v.ViewName == view.ViewName);
bool sameview2 = view.Id == sameView1.Id;

bool ViewExists = db.View.Any(v => v.ViewName == view.ViewName);
if (ViewExists && !sameview2)
{
ModelState.AddModelError("ViewName", UI_Prototype_MVC_Resources.ErrorViewAlreadyExists);
return View(view);
}

bool PathExists = db.View.Any(v => v.ViewPath == view.ViewPath);
if (PathExists && !sameview2)
{
ModelState.AddModelError("ViewPath", UI_Prototype_MVC_Resources.ErrorPathAlreadyExists);
return View(view);
}

if (ViewExists && PathExists && sameview2)
{
if (ModelState.IsValid)
{
db.Entry(view).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
}

return View(view);
}

下面是创建 Controller 操作的 POST 方法。这工作正常,仅供引用,它可以帮助任何人:

public ActionResult Create(View view)
{
bool ViewExists = db.View.Any(v => v.ViewName == view.ViewName);
if (ViewExists)
{
ModelState.AddModelError("ViewName", UI_Prototype_MVC_Resources.ErrorViewAlreadyExists);
return View(view);
}

bool PathExists = db.View.Any(v => v.ViewPath == view.ViewPath);
if (PathExists)
{
ModelState.AddModelError("ViewPath", UI_Prototype_MVC_Resources.ErrorPathAlreadyExists);
return View(view);
}

if (!ViewExists && !PathExists)
{
if (ModelState.IsValid)
{
view.ViewContent = "<p>Initial Content</p>";

db.View.Add(view);
db.SaveChanges();

return RedirectToAction("Index");
}
}

return View(view);
}

如果添加评论有帮助,请告诉我,我会进行编辑。本质上它只是从资源文件中读取错误字符串。它还只是读取 ViewName、ViewPath 以检查记录是否已存在。

在编辑 Controller 操作的情况下,有一个额外的检查来拉回当前的记录 ID,以验证如果我们更改名称,记录仍然是相同的(因此它不匹配基于现有的记录在 ViewName 上)。

Encase 对任何人都有帮助,我对数据库中的 ViewName 和 ViewPath 字段有独特的约束。如果字段不唯一并且由于某些奇怪的原因未在代码中处理,这些将导致代码中出现异常。

我不禁觉得这里太复杂了?

最佳答案

是的,你把它弄得太复杂了,你可以通过检查它是否有效来简化你的代码并减少数据库调用的次数

bool isViewNameInvalid = db.View.Any(v => v.ViewName == view.ViewName && v.Id != view.Id)

ViewPath 也是如此。您还应该考虑在返回 View 之前进行这两项检查,这样如果用户有这两个错误,他们就不需要进行额外的提交来通知第二个错误。

另请注意,您的 View sameView1 = db.View.First(v => v.ViewName == view.ViewName); 代码行可能不会返回 View 您期望的记录(它可能是您编辑的记录或以前创建的具有相同 ViewName 值的记录),这可能会导致意外结果。

你的代码可以简化为

public ActionResult Edit([Bind(Include = "Id,ViewName,ViewPath,ViewContent")] View view)
{
bool isViewNameInvalid = db.View.Any(v => v.ViewName == view.ViewName && v.Id != view.Id)
if (isViewNameInvalid)
{
ModelState.AddModelError("ViewName", UI_Prototype_MVC_Resources.ErrorViewAlreadyExists);
}
bool isViewPathInvalid = db.View.Any(v => v.ViewPath == view.ViewPath && v.Id != view.Id)
if (isViewPathInvalid)
{
ModelState.AddModelError("ViewName", UI_Prototype_MVC_Resources.ErrorPathAlreadyExists);
}
if (!ModelState.IsValid)
{
return View(view);
}
// Save and redirect
db.Entry(view).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index")
}

作为旁注,您可以考虑在 ViewNameViewPath 属性上实现 RemoteAttribute 以提供客户端验证(引用 How to: Implement Remote Validation in ASP.NET MVC ).在您的情况下,您会将 Id 值作为 additionalFields 传递。

并且由于您的编辑数据,我建议您使用 View 模型(并删除 [Bind] 属性 - 引用 What is ViewModel in MVC?

关于c# - 确保另一条记录不包含字段的相同值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39260932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com