使用Entity Framework在DB中获取重复记录

时间:2016-01-14 17:36:54

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

我有一个表现奇怪的ASP.Net MVC网站。几乎重复的记录正在创建中。记录中唯一不同的字段是Key / Id字段。两个记录中都有一个datetime字段完全相同。使问题复杂化的是,每创建一百条记录只会发生一次或两次。由于重复记录中的StartTime是相同的,我认为它必须发生在上下文Add和上下文SaveChanges调用之间的某处。我正在使用EntityFramework 6.1.3

  [HttpPost]
    public JsonResult LogTime(CheckinVM checkin)
    {
     var employee = db.Employees.FirstOrDefault(e => e.CompanyId.Equals(checkin.EmployeeId));           
     var dept = db.Departments.Find(checkin.DepartmentId);
     var currentWage = db.Wages.Where(w => w.Department.Id.Equals(checkin.DepartmentId))
        .Where(w => w.Employee.CompanyId.Equals(checkin.EmployeeId))
        .Where(w => w.EffectiveDateTime < DateTime.Now)
        .OrderByDescending(w => w.EffectiveDateTime)
        .ThenByDescending(w => w.Id).Select(w => w.Amount)
        .FirstOrDefault();

     var tc = new TimeCard
            {
            StartTime = DateTime.Now,
            EnteredBy = User.Identity.Name,
            LastEdit = DateTime.Now,
            LastEditedBy = "Timecard UI",
            Department = dept,
            Employee = employee,
            Wage = currentWage
            };
     db.TimeCards.Add(tc);
     db.SaveChanges();
     return Json(test, JsonRequestBehavior.AllowGet);
    }

这是通过Jquery ajax调用

发布的
$('.campaign').click(function () {
     var id = this.id;
     $('#'+id).prop("disabled", true);
     var employeeId = $('#EmployeeId').val();
     var dept = $('#' + id).data("dept");
     var checkin = {
               EmployeeId: employeeId,
               DepartmentId: dept
              };
    $.ajax({
          url: "@Url.Action("LogTime","Home")",
          type: "POST",
          contentType: "application/json",
          data: JSON.stringify({ Checkin: checkin })
          })
          .done(function (data) {$('#'+id).prop("disabled", false);});
     });

Timecard类和表是通过针对SQL 2012 DB的代码优先进程创建的。

 [Table("TimeCards", Schema = "TCT")]
public class TimeCard
{
    [Display(Name = "Timecard Id")]
    public int Id { get; set; }

    [Display(Name = "Start Time")]
    [DisplayFormat(NullDisplayText = "N/A")]
    public DateTime? StartTime { get; set; }

    [Display(Name = "End Time")]
    [DisplayFormat(NullDisplayText = "Open")]
    public DateTime? EndTime { get; set; }

    public virtual Department Department { get; set; }

    public virtual Employee Employee { get; set; }

    [DataType(DataType.Currency)]
    public float? Wage { get; set; }

    [Display(Name = "Entered By")]
    public string EnteredBy { get; set; }

    [Display(Name = "Last Edited")]
    [DisplayFormat(NullDisplayText = "N/A")]
    public DateTime? LastEdit { get; set; }

    [Display(Name = "Last Edited By")]
    [DisplayFormat(NullDisplayText = "N/A")]
    public string LastEditedBy { get; set; }

    [Display(Name = "Deleted")]
    public bool IsDeleted { get; set; }

    [NotMapped]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = @"{0:hh\:mm}")]
    public TimeSpan? Hours
    {
        get
        {
            var t = EndTime - StartTime;
            return t;
        }
        private set { }
    }
}

1 个答案:

答案 0 :(得分:-1)

之前发生过我。我正在走出困境并猜测第一条记录是从表读取实体框架更改跟踪缓存,然后第二条记录直接从缓存中读取。

解决方案:

  • AsNoTracking()子句添加到您的查询中,以防止它们被读入缓存,请参阅Julie Lerman的article以获取更多信息。

其他可能的提示和技巧:

  • 使用jQuery
  • 禁用单击后调用该方法的按钮
  • 在Entity Framework中使用锁定,或者将数据库的事务隔离级别设置为可序列化的,作为查找EF是否实际上第二次进入数据库的临时步骤 - 您将看到错误1205如果您成功复制它,则表示死锁。
  • 调用方法的html按钮也发送GUID或随机生成的字符串,你会看到它是否肯定是两次调用HTML请求 - 即在你jquery序列化它之前,用一个新的更新一些随机字段GUID。