我有这段代码:
try
{
newJob.Company = ((CustomPrincipal)HttpContext.Current.User).MyUser.WorkinCompany;
Random rnd = new Random();
newJob.JobId = rnd.Next(1000000, 10000000);
realjob.RelatedJobs.Add(newJob);
_db.Entry(realjob).State = EntityState.Modified;
}
catch (Exception e)
{
}
我得到了这个例外:
附加“MySolution.Models.Register.MyUser”类型的实体 失败,因为同一类型的另一个实体已经相同 主键值。使用“附加”方法或时,可能会发生这种情况 将实体的状态设置为“未更改”或“已修改”(如果有) 图中的实体具有冲突的键值。这可能是因为 某些实体是新的,尚未收到数据库生成的密钥 值。在这种情况下,使用“添加”方法或“已添加”实体状态 跟踪图形,然后将非新实体的状态设置为 “视情况而定”或“修改”。
如何摆脱这种异常?感谢。
答案 0 :(得分:0)
首先,你的随机函数rnd.Next(100000,1000000)
将最终返回一个已经存在于你的数据库中的int(可能不是你使用它的前3次,但是过了一段时间,它确定)。
所以难怪你总是会遇到重复的主键异常。
然后,使用random不是为新实体生成主键的正确方法,请考虑以下选项:
查询表格以查找主键的最大值,并为其添加+1,如果它不存在,则输入1.
使用数据库集成的indentity列,只需添加没有主键的实体,主键将自动生成
答案 1 :(得分:0)
重复(?):
Error attaching entity because of same primary key when trying to save an update
Attaching an entity of type 'X' failed because another entity of the same type
您的代码的其他[MAJOR]问题与您收到的错误没有直接关系,因为错误明确说明问题出在类DegerlemeTakip.Models.Register.MyUser ...
假设JobID是Job类的主键,将其设置为随机值并不是一个好主意。将JobID属性标记为生成的数据库,让DB担心设置密钥并删除将PK设置为随机值的行。
假设:
public class Job
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int JobID { get; set;}
}
将您的代码更改为:
try
{
newJob.Company = ((CustomPrincipal)HttpContext.Current.User).MyUser.WorkinCompany;
realjob.RelatedJobs.Add(newJob);
_db.Entry(realjob).State = EntityState.Modified;
}
catch (Exception e)
{
//Please do something with the exception!
}
此外,不需要将realJob的状态设置为Modified。除非您有特定原因,否则请删除此行:
_db.Entry(realjob).State = EntityState.Modified;
如果必须随机设置JobID,则在尝试将JobID附加到数据上下文之前,需要检查以确保随机分配的JobID尚未使用:
try
{
newJob.Company = ((CustomPrincipal)HttpContext.Current.User).MyUser.WorkinCompany;
Random rnd = new Random();
newJob.JobId = rnd.Next(1000000, 10000000);
// Keep Trying Random JobIDs until one doesn't already exist in the database
while(_db.Jobs.Any(j => j.JobID == newJob.JobID))
newJob.JobId = rnd.Next(1000000, 10000000);
realjob.RelatedJobs.Add(newJob);
_db.Entry(realjob).State = EntityState.Modified;
}
catch (Exception e)
{
//Please do something with the exception!
}
上面的代码仍然存在重大问题,例如,一旦你在表中有9,000,000个作业,就没有剩余的ID可以分配,你的代码将永远循环,但你可以弄清楚,如果你绝对必须设置从代码中随机输入密钥。