Sql server 使用实体框架更新数据库中的模型导致与外键冲突

Sql server 使用实体框架更新数据库中的模型导致与外键冲突,sql-server,asp.net-mvc,entity-framework,Sql Server,Asp.net Mvc,Entity Framework,我知道这个问题已经被问了数百万次,我自己也问过几百次,但由于某种原因,我无法解决这个问题 我得到了一个众所周知的错误: The UPDATE statement conflicted with the FOREIGN KEY constraint ... 插入或删除操作完成后,数据库中的所有表都将级联 现在来看错误: 我想更新链接到文化表(用于语言)的管理员表(管理员帐户) 一切都填对了。因此,我们得到以下代码: [HttpPost] public ActionResult E

我知道这个问题已经被问了数百万次,我自己也问过几百次,但由于某种原因,我无法解决这个问题

我得到了一个众所周知的错误:

The UPDATE statement conflicted with the FOREIGN KEY constraint ...
插入或删除操作完成后,数据库中的所有表都将级联

现在来看错误: 我想更新链接到文化表(用于语言)的管理员表(管理员帐户)

一切都填对了。因此,我们得到以下代码:

    [HttpPost]
    public ActionResult Edit(Admins admins)
    {
        if (!ModelState.IsValid)
        {
            return View(admins);
        }
        admins.cultures_id = admins.Cultures.id;
        _unitOfWork.AdminsRepository.Update(admins);
        _unitOfWork.Save();

        return RedirectToAction("Index", "Overview", new { area = "Admin" });
    }
我首先将我的管理对象/实体的文化id设置为链接的文化表中的id:

admins.cultures_id = admins.Cultures.id;
然后填写并更新表格:

_unitOfWork.AdminsRepository.Update(管理员)

方法更新保存以下代码:

    public virtual void Update(TEntity entityToUpdate)
    {
        DbSet.Attach(entityToUpdate);
        ArtWebShopEntity.Entry(entityToUpdate).State = EntityState.Modified;
    }
        public void Save() {
        try
        {
            _artWebshopEntity.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", validationErrors.Entry.Entity.GetType().Name, validationErrors.Entry.State);

                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", validationError.PropertyName, validationError.ErrorMessage);
                }
            }

            throw;  // Will do something here later on...
        }

    }
到目前为止还不错,但是,当我真的想保存管理员时:

_unitOfWork.Save();
该保存方法保存以下代码:

    public virtual void Update(TEntity entityToUpdate)
    {
        DbSet.Attach(entityToUpdate);
        ArtWebShopEntity.Entry(entityToUpdate).State = EntityState.Modified;
    }
        public void Save() {
        try
        {
            _artWebshopEntity.SaveChanges();
        }
        catch (DbEntityValidationException dbEx)
        {
            foreach (var validationErrors in dbEx.EntityValidationErrors)
            {
                Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", validationErrors.Entry.Entity.GetType().Name, validationErrors.Entry.State);

                foreach (var validationError in validationErrors.ValidationErrors)
                {
                    Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"", validationError.PropertyName, validationError.ErrorMessage);
                }
            }

            throw;  // Will do something here later on...
        }

    }
在SaveCHanges方法中,我得到了错误。我知道这意味着什么,但我似乎无法修复它。我已经尝试了所有我知道的可能导致它的事情

编辑 我只想更新管理值,所以我不想更新区域性值

以下是查询:

update [dbo].[Admins]
set    [login] = 'Herve' /* @0 */,
       [password] = null,
       [salt] = null,
       [email] = 'xxxxx.xxx@glevin.be' /* @1 */,
       [permissions] = 'administrator' /* @2 */,
       [attempts] = 4 /* @3 */,
       [locked] = 0 /* @4 */,
       [cultures_id] = 0 /* @5 */
where  ([id] = 1 /* @6 */)
所以,文化是个问题。我现在做了以下工作:

        var updateAdmin = new Admins
            {
                attempts = admins.attempts,
                cultures_id = admins.cultures_id,
                email = admins.email,
                locked = admins.locked,
                login = admins.login,
                id = admins.id,
                password = admins.password,
                permissions = admins.permissions,
                salt = admins.salt,
            };
@Html.EditorFor(model => model.Cultures.name)
这是可行的,但当我将Cultures对象添加到混合中时,它崩溃了,并给出了引用错误。因此,它归结为,我如何用外键将一个表更新到另一个也需要更新的表

编辑二 我的管理和文化实体(数据库优先),也是sql management studio中数据库的映像:

管理类:

public partial class Admins
{
    public int id { get; set; }
    public string login { get; set; }
    public string password { get; set; }
    public string salt { get; set; }
    public string email { get; set; }
    public string permissions { get; set; }
    public Nullable<int> attempts { get; set; }
    public Nullable<bool> locked { get; set; }
    public Nullable<int> cultures_id { get; set; }

    public virtual Cultures Cultures { get; set; }
}
公共部分类管理员
{
公共int id{get;set;}
公共字符串登录{get;set;}
公共字符串密码{get;set;}
公共字符串salt{get;set;}
公共字符串电子邮件{get;set;}
公共字符串权限{get;set;}
公共可为空的尝试{get;set;}
公共可空锁定{get;set;}
公共可为空的区域性\u id{get;set;}
公共虚拟区域性{get;set;}
}
文化课:

public partial class Cultures
{
    public Cultures()
    {
        this.Categories_local = new HashSet<Categories_local>();
        this.Menu_items_local = new HashSet<Menu_items_local>();
        this.Products_local = new HashSet<Products_local>();
        this.Subcategories_local = new HashSet<Subcategories_local>();
        this.Webpages_local = new HashSet<Webpages_local>();
        this.Admins = new HashSet<Admins>();
    }

    public int id { get; set; }
    public string name { get; set; }
    public string display_name { get; set; }

    public virtual ICollection<Categories_local> Categories_local { get; set; }
    public virtual ICollection<Menu_items_local> Menu_items_local { get; set; }
    public virtual ICollection<Products_local> Products_local { get; set; }
    public virtual ICollection<Subcategories_local> Subcategories_local { get; set; }
    public virtual ICollection<Webpages_local> Webpages_local { get; set; }
    public virtual ICollection<Admins> Admins { get; set; }
}
公共部分类区域性
{
公共文化()
{
this.Categories_local=new HashSet();
this.Menu_items_local=new HashSet();
this.Products_local=new HashSet();
this.Subcategories_local=new HashSet();
this.Webpages_local=new HashSet();
this.Admins=new HashSet();
}
公共int id{get;set;}
公共字符串名称{get;set;}
公共字符串显示\u名称{get;set;}
公共虚拟ICollection类别\u local{get;set;}
公共虚拟ICollection菜单\u项\u本地{get;set;}
公共虚拟ICollection产品\u local{get;set;}
公共虚拟ICollection子类别\u local{get;set;}
公共虚拟ICollection网页\u local{get;set;}
公共虚拟ICollection管理员{get;set;}
}

我已经让它工作了

问题是,在编辑页面中,最后一个字段是显示与管理员id对应的区域性名称的字段

换句话说,我做到了以下几点:

        var updateAdmin = new Admins
            {
                attempts = admins.attempts,
                cultures_id = admins.cultures_id,
                email = admins.email,
                locked = admins.locked,
                login = admins.login,
                id = admins.id,
                password = admins.password,
                permissions = admins.permissions,
                salt = admins.salt,
            };
@Html.EditorFor(model => model.Cultures.name)
但这不是正确的方法

为了显示区域性的名称,但在传递区域性id的代码中,我使用了@Html.DropDownListFor()-元素

然而,问题是我的原始模型,Admins,没有一个IEnumerable对象可以传递给视图中的dropdownlist元素。我必须创建一个名为CreateAdminModel的新模型,新模型如下所示:

public class CreateAdminModel
{
    public CreateAdminModel() { }

    public CreateAdminModel(IEnumerable<SelectListItem> cultures) { Cultures = cultures; }

    public CreateAdminModel(Admins admin) { Admin = admin; }

    public CreateAdminModel(IEnumerable<SelectListItem> cultures, Admins admin)
    {
        Cultures = cultures;
        Admin = admin;
    }

    public IEnumerable<SelectListItem> Cultures { get;  set; }
    public Admins Admin { get; internal set; }
}
public类CreateAdminModel
{
公共CreateAdminModel(){}
公共CreateAdminModel(IEnumerable cultures){cultures=cultures;}
公共CreateAdminModel(管理员管理员){admin=admin;}
公共CreateAdminModel(IEnumerable区域性,Admins-admin)
{
文化=文化;
管理员=管理员;
}
公共IEnumerable区域性{get;set;}
公共管理员管理{get;内部集合;}
}
它有一个由实体框架创建的管理对象(首先是数据库)

使用该新模型,我创建了以下方法:

    private CreateAdminModel CreateAdminWithcultureDetails(Admins admin = null)
    {
        var cultureItems = (_unitOfWork.CulturesRepository.Get()).ToArray();
        var cultureList = new List<SelectListItem>();
        for (int i = 0; i < cultureItems.Count(); i++) cultureList.Add(new SelectListItem { Text = cultureItems[i].name, Value = cultureItems[i].id.ToString() });

        return admin != null ? new CreateAdminModel(cultureList, admin) : new CreateAdminModel(cultureList);
    }
private CreateAdminModel CreateAdminWithcultureDetails(Admins admin=null)
{
var cultureItems=(_unitOfWork.CulturesRepository.Get()).ToArray();
var cultureList=新列表();
对于(int i=0;i
这将使用区域性填充下拉列表,并根据是否传递了管理对象添加管理对象

现在我可以在视图中使用此模型,并在必要时正确填充下拉列表和管理员


对于其他必须使用CRUD的东西,我也要这样做。

启动SqlProfiler以查看正在执行的查询。这应该表明缺少了什么。我在哪里可以找到它?您可以在SQL Manager Studio中找到SQL探查器。也可以在express版本中找到?因为我似乎找不到它。不确定SQL Express Management Studio中是否存在SQL探查器。