插入时重复数据库记录

时间:2014-05-06 02:24:35

标签: c# sql .net asp.net-mvc entity-framework

我正在试图找出为什么当我将JobOffert记录插入到我的MS SQL Server数据库中时,我得到的是JobOffert属性的My Professional的重复记录,让我展示我的代码:

这是我的控制器发布方法

[HttpPost]
public ActionResult CreateJobOffert(JobOffertModel jobOffert, FormCollection data)
{
    initBusinessObjects();

    Util.Util.ChangeContextInstance(customerBusiness, null, skillBusiness, jobOffertBusiness);

    var allSkills = skillBusiness.GetAllSkills();
    var allProfessionals = professionalBusiness.GetAllElements();
    //Se eu recarregar a mesma página eu tenho que carregar os ViewBags

    if (ModelState.IsValid)
    {
        var customerId = int.Parse(data["customerId"]);
        var professionalId = int.Parse(data["professionalsList"]);

        var customer = customerBusiness.GetById(customerId);
        var professional = professionalBusiness.GetById(professionalId);

        var skillsIds = data["requiredSkills"].Split(',').Select(x => int.Parse(x));

        jobOffert.Skills = allSkills.Where(x => skillsIds.Contains(x.Id)).ToList();
        jobOffert.Customer = customer;

        if (jobOffert.Active)
        {
            jobOffert.Professional = professional;
        }

        jobOffertBusiness.Insert(jobOffert);

        return View("Edit", customer);
    }

    return View("CreateJobOffert", jobOffert);
}

此处我按ID ID 返回我的专业人员:

public ProfessionalModel GetProfessionalById(int id)
{
    var professional = Context.ProfessionalContext
                                .Include(x => x.UserAccount)
                                .Include(x => x.UserAddress)
                                .Include(x => x.Skills)
                                .Include(x => x.Skills.Select(y => y.Category))
                                .Include(x => x.Tasks)
                                .FirstOrDefault(x => x.Id == id);

    return professional;
}

这很奇怪,因为我的客户,JobOffert的另一个属性没有重复,这里我得到了我的客户

public CustomerModel GetCustomerById(int id)
{
    var customer = Context.CustomerContext
                                .Include(x => x.UserAccount)
                                .Include(x => x.UserAddress)
                                .Include(x => x.JobOfferts)
                                .FirstOrDefault(x => x.Id == id);

    return customer;
}

这是我的 JobOffertModel

public class JobOffertModel
{
    [Key]
    public int Id { get; set; }

    public ProfessionalModel Professional { get; set; }

    [Required]
    public string Description { get; set; }

    [Required]
    [DefaultValue(false)]
    public bool Acepted { get; set; }

    [Required]
    [DefaultValue(true)]
    public bool Active { get; set; }

    public ICollection<SkillModel> Skills { get; set; }

    [Required]
    [Column(TypeName = "DateTime2")]
    public DateTime JobDate { get; set; }

    public virtual CustomerModel Customer { get; set; }
}

任何想法?我该如何解决这个问题并停止复制我的专业记录?

谢谢!

修改

嗨,我得到了好消息,我做到了,但坏消息是我不知道为什么会这样。 我必须再次选择我的专业人员,但这一次,当我迈出存储数据的一步时,这是我的旧插入JobOffert 方法:

        public void Insert(JobOffertModel jobOffertModel)
        {
            Context.JobOffertContext.Add(jobOffertModel);
            Context.SaveChanges();
        }

这是我新的Insert JobOffert方法:

        public void Insert(JobOffertModel jobOffertModel)
        {
            var professional = Context.ProfessionalContext.Include(x => x.UserAccount)
                                        .Include(x => x.UserAddress)
                                        .Include(x => x.Skills)
                                        .Include(x => x.Skills.Select(y => y.Category))
                                        .Include(x => x.Tasks)
                                        .FirstOrDefault(x => x.Id == jobOffertModel.Professional.Id);
            jobOffertModel.Professional = professional;

            Context.JobOffertContext.Add(jobOffertModel);
            Context.SaveChanges();
        }

所以,现在我改变了我的问题,为什么使用第二种方法可行并使用第一种方法呢?

再次感谢!

2 个答案:

答案 0 :(得分:1)

关键是DbSet.Add将对象图中的所有对象标记为尚未附加到上下文的Added。即使对象具有主键值,EF也会插入它并生成新的PK值。

在第一个插入方法中,professional未附加到执行插入的上下文。在第二种方法中,它是因为您在设置jobOffertModel.Professional之前获取它。

答案 1 :(得分:0)

插入代码1

此处您不进行任何验证,只需将数据添加到JobOffertContext表即可。因此,无论每次将新记录添加到db时,数据库中存在的值都是新的。

public void Insert(JobOffertModel jobOffertModel)
{
    Context.JobOffertContext.Add(jobOffertModel);
    Context.SaveChanges();
}

插入代码2

此处首先使用FirstOrDefault();取出已插入的数据,然后在找到记录后更新Professional字段,然后保存。因此,现在您没有重复记录,因为没有插入新记录而是已更新。如果记录不存在,则FirstOrDefault将返回null,jobOffertModel.Professional将获得null值并将其插入到db中。

public void Insert(JobOffertModel jobOffertModel)
{
    var professional = Context.ProfessionalContext.Include(x => x.UserAccount)
                                .Include(x => x.UserAddress)
                                .Include(x => x.Skills)
                                .Include(x => x.Skills.Select(y => y.Category))
                                .Include(x => x.Tasks)
                                .FirstOrDefault(x => x.Id == jobOffertModel.Professional.Id);

    jobOffertModel.Professional = professional;

    Context.JobOffertContext.Add(jobOffertModel);
    Context.SaveChanges();
}