确保另一条记录尚未包含一个字段的值相同 [英] Ensuring another record does not already contain the same value for a field

查看:154
本文介绍了确保另一条记录尚未包含一个字段的值相同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在建筑使用C#MVC我自己的学术用途的小型内容管理系统的过程。

I am in the process of building a small content management system for my own academic purposes using C# MVC.

我有功能来创建页面(列表页面,删除网页等等等等。)

I have functionality to create page (list pages, delete pages etc. etc.)

在基本层面,我用一个ID来验证所有页面都是独一无二的。但正如我使用MVC,页面本质上是一个视图 - 它可以包含刮胡刀。这一切工作没有问题。

At a basic level, I use an ID to verify all pages are unique. But as I am using MVC, a page is essentially a View - and it can contain razor. All this works no problem.

不过我也VIEWNAME必须是唯一的(你不能在数据库具有相同名称的两个视图)。也是我ViewPath必须是唯一的(你不能有两个途径是相同的)。

However my ViewName must also be unique (you cant have two views in the database with the same name). Also my ViewPath must be unique (you cant have two routes that are identical).

在我创建页面,我检查(所有工作),以确保一个新的观点是一个唯一的ID创建的,之前创建视图,无论是VIEWNAME和ViewPath是独一无二的,如果不返回相关的错误,它会检查。

In my create page, I have checks (all working) to ensure a new view is created with a unique ID, and it checks prior to creating the view that both the ViewName and ViewPath are unique returning relevant errors if not.

这所有的作品。

现在,当我去编辑视图。用户具有改变VIEWNAME和ViewPath的选项。因此,我们需要确保它不会改变到一个视图名和ViewPath已经存在。然而,当我们正在编辑的视图,视图本身已经存在,所以我们得到这些错误这样说。

Now when I go to edit a view. The user has the option to alter the ViewName and ViewPath. So we need to ensure it is not altered to a ViewName and ViewPath that already exists. However as we are editing the view, the view itself already exists so we get these errors saying so.

因此,我们需要检查我们是否保存到同一个页面,以便我们寻找与当前的VIEWNAME VIEWNAME的数据库记录的ID(因为是视图名唯一的,因此我们可以得到ID),并验证我们的确是保存到了同样的观点。然后,我们可以用这个检查,以确保我们不显示上面的错误,因为我们只是更改视图的名称,它不匹配任何现有视图。

So we need to check if we are saving to the same page so we look for the id of the record in the DB of the ViewName with the current ViewName (because ViewNames are unique, so we can get the ID), and verify that we are indeed saving to the same view. Then we can use this check to ensure that we don't show the above errors because we are simply changing the name of the view and it doesn't match any existing view.

问题是我收到以下错误,当我打的行

The problem is I get the following error when I hit the line

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



该错误是:

The error is:

更多信息:连接类型的实体'XXX'失败
,因为同类型的另一实体已经具有相同的主
键值。这可以通过当'连接'方法或设置b一个实体的状态$ B $发生'不变'或'修改'如果$ B $的任何实体B中的图有冲突的键值。这可能是因为一些
实体是新的,但尚未收到数据库生成的密钥
值。在这种情况下使用添加方法或增加了实体状态
跟踪的图形,然后设置非新实体的状态,
'不变'或'修改'为宜。

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.

问:
我不知道如果我在我的解决方案复杂,如果是这样,有人可以请告知更好解决方案用一个例子。

QUESTION: I don't know if I am over complicating my solution, if so, can someone please advise a better solution with an example.

如果这是正确的道路,但我刚刚实施错不知何故,有人可以告诉我怎么解决它。

If this is the correct "way" but I have just implemented it wrong somehow, can someone show me how to fix it.

下面是我在哪里有问题编辑控制器动作的POST方法:

Below is the POST method of the Edit controller action where I am having the problem:

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);
}



下面是创建控制器动作的POST方法。这是工作的罚款,它只是一个参考包住它可以帮助任何人:

Below is the POST method of the Create controller action. This is working fine, it's just for reference encase it helps anyone:

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);
}

如果添加评论将帮助任何只是让我知道,我会修改。从本质上讲它只是读取从资源文件的错误字符串。它也只是做了几个读取视图名,ViewPath的检查的记录已经存在。

If adding comments would help any just let me know and I'll edit. Essentially its just reading the error strings from resource files. Its also just doing a couple of reads of the ViewName, ViewPath to check if a record already exists.

在编辑控制器动作的情况下,还有一个额外的检查给拉了回来当前记录的ID来验证,如果我们改变成绩仍然是相同的名称(所以它不匹配基础上,VIEWNAME现有记录)。

In the case of the Edit controller action, there is an additional check to pull back the current records id to verify that if we change the name that the record is still the same (so it doesn't match an existing record based on the ViewName).

包住它可以帮助任何,我必须在数据库的视图名和ViewPath领域唯一约束。这将导致在该领域不是唯一和它不是在代码中处理一些奇怪的原因案件的代码例外。

Encase it helps any, I do have unique constraints on the ViewName and ViewPath fields in the DB. These will cause exceptions in the code in the cases where the fields are not unique and for some odd reason it is not handled in the code.

我不禁思考有太多的复杂性在这里?

I can't help thinking there is too much complexity here?

推荐答案

是的,你过复杂,并可以简化您的代码和减少数据库的数量通过检查调用如果使用有效

Yes, your over complicating it and you can simplify your code and reduce the number of database calls by checking if its valid using

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

和同上,用于 ViewPath 。你也应该考虑返回视图之前做两个检查,所以如果用户有两个错误,他们并不需要在订购T被告知第二误差额外提交。

and ditto for ViewPath. You should also consider making both checks before returning the view so if the user has both errors, they do not need to make a extra submit in order t be informed of the 2nd error.

还要注意你的查看sameView1 = db.View.First(v => v.ViewName == view.ViewName); 的代码行可能不会返回在查看记录你所期望(也可能是您的一个编辑或之前创建的具有相同 VIEWNAME 值)这可能会导致意想不到的结果。

Note also that your View sameView1 = db.View.First(v => v.ViewName == view.ViewName); line of code may not be returning the View record you expect (it could be the one your editing or a previously created one with the same ViewName value) which could cause unexpected results.

您的代码可以简化为

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")
}



作为一个方面说明,你可以考虑实施 RemoteAttribute VIEWNAME ViewPath 性能给你客户端验证(参见如何:实现远程在ASP.NET MVC 验证)。在你的情况,你会通过编号 additionalFields

As a side note, you could consider implementing a RemoteAttribute on the ViewName and ViewPath properties to give you client side validation (refer How to: Implement Remote Validation in ASP.NET MVC). In your case you would pass the Id value as additionalFields.

和因为你的编辑数据,我建议你使用一个视图模型(并删除 [绑定] 属性 - 指的什么是视图模型在MVC?

And since your editing data, I recommend you use a view model (and remove the [Bind] attribute - refer What is ViewModel in MVC?.

这篇关于确保另一条记录尚未包含一个字段的值相同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆