实体框架不断创建多个记录

时间:2013-10-20 15:54:07

标签: c# linq entity-framework model foreign-keys

我遇到了这种特殊方法的问题。我第一次保存它的工作原理是在AppointmentEvent中创建一条记录并在Appointment中更改已验证的变量,但它会再次创建用户记录。

private void CreateAppointment(Employee user)
        {
            try
            {
                using (var db = new CosmeticContext())
                {
                    Appointment appointment = db.Appointment.FirstOrDefault(o => o.name == phoneNumber.name && o.surname == phoneNumber.surname && o.verified == false);
                    appointment.verified = true;
                    PhoneNumber ph = db.PhoneNumber.FirstOrDefault(o => o.name == phoneNumber.name && o.surname == phoneNumber.surname);
                    db.PhoneNumber.Remove(ph);
                    db.AppointmentEvent.Add(new AppointmentEvent
                    {
                        date = DateTime.Now,
                        Employees = user,
                        Appointments = appointment,
                        EventComment = EventComment.Save
                    });
                    db.SaveChanges();
                }
          }
            catch (System.Data.Entity.Validation.DbEntityValidationException e)
            {
                DbScript.ShowEntityErrors(e);
            }
        }

当我第二次运行它时,它会复制user,appointmentEvent和具有先前值的约会记录。当我通过调试器时,我看到db.AppointmentEvent.Local有0条记录,但是第二次Add方法在db.AppointmentEvent.Local中创建了2条记录。我不明白一个Add方法如何添加2条记录。谷歌在为我展示合适的案例方面没有帮助,但是使用块不应该正确处理所有内容吗?

以下是一些其他类,其中包含此处使用的对象:

public class Employee
{
    [Key]
    public int employeeId { get; set; }
    [Required, MaxLength(25), MinLength(4)]
    public string userName { get; set; }
    [Required, MaxLength(25), MinLength(4)]
    public string firstName { get; set; }
    [Required, MaxLength(25), MinLength(4)]
    public string lastName { get; set; }
    [Required, MaxLength(100), MinLength(20)]
    public string password { get; set; }
    [Required]
    public EmployeeType EmployeeType { get; set; }
    public virtual List<PhoneNumber> PhoneNumbers { get; set; }
    public virtual List<AppointmentEvent> AppointmentEvents { get; set; }
}

public class AppointmentEvent
{
    public int appointmentEventId { get; set; }
    [Required]
    public DateTime date { get; set; }
    [Required]
    public virtual Employee Employees { get; set; }
    [Required]
    public virtual Appointment Appointments { get; set; }
    [Required]
    public EventComment EventComment { get; set; }
}

public class Appointment
{
    [Key]
    public int appointmentId { get; set; }
    [Required, MaxLength(20)]
    public string name { get; set; }
    [Required, MaxLength(30)]
    public string surname { get; set; }
    [Required, MaxLength(20), Phone]
    public string phone { get; set; }
    [Required]
    public DateTime date { get; set; }
    [Required]
    public ServiceType ServiceType { get; set; }
    [Required]
    public bool verified { get; set; }
    public virtual List<AppointmentEvent> AppointmentEvents { get; set; }
}
编辑:忘了告诉我正在创建一个Windows窗体应用程序和更多代码,它显示了用户部分: 这是表格nr2.:(其中我有记录的问题)

    public partial class CallCenter : Form
    {
        Employee employee;
        static ListTime listTime = new ListTime();
        Button pushedButton = new Button();

        public CallCenter(Employee loginEmployee)
        {

            employee = loginEmployee;

            InitializeComponent();
            tableLayoutPanel2.CellPaint += tableLayoutPanel1_CellPaint;
            GeneratedServiceTypeComboBox.DataSource = Enum.GetValues(typeof(ServiceType));
            textBox1.Text = DateTime.Now.AddDays(1).Date.ToString("dd.MM.yyyy");
            textBox2.Text = DateTime.Now.AddDays(2).Date.ToString("dd.MM.yyyy");
            RefreshAppointmentAvailabilityTable();
        }

   private void SaveButton_Click(object sender, EventArgs e)
        {
            try
            {
                GenerateButton.Enabled = true;
                SaveButton.Enabled = false;
                this.NameBox.Text = string.Empty;
                SurnameBox.Text = string.Empty;
                PhoneBox.Text = string.Empty;
                GeneratedNameBox.Text = string.Empty;
                GeneratedSurnameBox.Text = string.Empty;
                GeneratedPhoneBox.Text = string.Empty;
                pushedButton.BackColor = Color.LightGreen;
                ChangeAppointmentAvailabilityButtonsStatus(false);
                CreateAppointment(employee);
            }
            catch (Exception f)
            { MessageBox.Show(f.ToString()); }

        }
    ...
    }

这是来自form1 :(登录屏幕)

    private void LoginButton_Click(object sender, EventArgs e)
    {
        using (var db = new CosmeticContext())
        {  
            bool verify = false;
            Employee employee = db.Employee.FirstOrDefault(o => o.userName == UserNameBox.Text);
            if (employee == null)
                MessageBox.Show("Sads lietotajs nav atrasts datubaze", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
            else
            {
                verify = PasswordAlgorithm.DoesPasswordMatch(employee.password, PasswordBox.Text);
                if (verify)
                    if (employee.EmployeeType == EmployeeType.Seller)
                    {
                        CallCenter form1 = new CallCenter(employee);
                        form1.Show();
                        this.Hide();
                    }
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

您的用户是否被EntityFramework上传跟踪? 如果没有跟踪,EF不会更好地知道,并且很乐意建立关联,但是通过添加新用户而不是将约会与现有关联相关联。我怀疑这就是这里发生的事情:

ObjectContext.AddObjectObjectSet.AddObject:  AddObject方法用于添加数据库中不存在的新创建的对象。实体将获得自动生成的临时EntityKey,其EntityState将设置为Added。调用SaveChanges时,EF将清楚该实体需要插入数据库。

ObjectContext.AttachObjectSet.Attach:  另一方面,Attach用于数据库中已存在的实体。而不是将EntityState设置为Added,将结果附加到Unchanged EntityState中,这意味着它自附加到上下文后没有更改。假定您附加的对象存在于数据库中。如果在附加对象后修改它们,则在调用SaveChanges时,EntityKey的值用于通过在db表中查找其匹配的ID来更新(或删除)相应的行。