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探查器。