2016-01-14 3 views
0

У меня есть сайт ASP.Net MVC, который ведет себя странно. Создаются почти дубликаты записей. Единственное поле, которое отличается в записях, - это поле Key/Id. В обеих записях есть поле даты и времени. Чтобы усложнить этот вопрос, это происходит только один или два раза за каждые несколько сотен записей. Поскольку StartTime в повторяющихся записях идентичен, я предполагаю, что это должно происходить где-то между контекстом Add и контекстом SaveChanges. Я использую EntityFramework 6.1.3Получение дубликатов записей в БД с использованием Entity Framework

[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); 
    } 

Это публикацией с помощью Ajax вызова Jquery

$('.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

Вы используете метод LogTime 2 раз? Можете ли вы поставить точку останова и подтвердить? – Shyju

+0

Вы называете свой ajax нажатием кнопки или каким-либо действием пользователя? Помните, что пользователь может «нажимать кнопку несколько раз до изменения страницы». без надлежащей проверки ваших запросов, это может привести к дублированию записей. – pnm

+0

Если бы я дважды бил метод LogTime, это не было бы точно таким же, вплоть до миллисекунды. Я попытался сделать несколько кликов как можно быстрее, и каждый раз, когда запись отличается по меньшей мере несколькими миллисекундами. –

ответ

-1

Это случилось раньше. Я выхожу на конечность и догадываюсь, что первая запись читает из таблицы в кеш отслеживания изменений Entity Framework, а вторая запись считывается прямо из кеша.

Решение:

  • Добавить статью AsNoTracking() на ваши запросы, чтобы предотвратить их от чтения в кэш, посмотреть article Джули Лерман для получения дополнительной информации.

Другие возможные советы и приемы:

  • Отключить кнопку, которая звонит метод после клика, используя JQuery
  • Использование блокировки в Entity Framework, или установить уровень изоляции транзакций базы данных, что-то вроде сериализуемого в качестве временного шага в определении того, действительно ли EF фактически идет в базу данных во второй раз - вы увидите ошибку 1205, указывающую на тупиковую ситуацию, если вы успешно ее реплицируете.
  • У вас есть кнопка html, которая вызывает метод, также отправляет GUID или случайно сгенерированную строку, и вы увидите, будет ли он, как правило, вызываться дважды в два раза, т. Е. До того, как вы выполните сериализацию jquery, обновите некоторое случайное поле с помощью нового GUID.
+0

Сначала нет записей. Приложение просто создает новые записи. Я отключил кнопку, как вы предлагали, но я все равно получаю случайные дубликаты. –

Смежные вопросы