Это только мой второй пост, прошу прощения за любые ошибки протокола.
У меня есть два обработчика Button-Click
, которые почти копируют и вставляют изображения, но имеют различия в поведении, которые вызывают проблемы (и разочарование)
Оба добавляют новые дочерние записи в базу данных сотрудников (Entity Framework 6, Code First
), один новый номер телефона, другой - должность.
Номер телефона:
private void btn_NewRecord_Click(object sender, EventArgs e)
{
if (thisNumber != null)
{
DbEntityEntry entry = _fDBC.Entry(thisNumber);
if (entry.State == EntityState.Modified)
{
// PROMPT to Save or Cancel current modified record
}
}
EmployeePhoneNumber newNumber = new EmployeePhoneNumber();
newNumber.EmployeeID = thisEmployee.EmployeeID;
int highestKey = _fDBC.EmployeePhoneNumbers // This is the only difference between these two Handlers,
// Phone Numbers use a non-automated multi-part Key
.Where(a => a.EmployeeID == thisEmployee.EmployeeID)
.Select(a => a.EmployeePhoneNumberID)
.DefaultIfEmpty(-1) // Default if set IS EMPTY
.Max();
newNumber.EmployeePhoneNumberID = highestKey + 1;
try
{
_fDBC.EmployeePhoneNumbers.Add(newNumber);
// INITIALIZING the Validation Checklist here
}
catch (DuplicateKeyException ex)
{
// Not getting any exceptions
}
bs_EmployeePhoneNumbers.MoveLast(); // This works fine for the new PhoneNumber
// The binding source sees the new record and moves to it,
// the new record is displayed on the Form.
thisNumber = newNumber;
}
Этот коддобавляет новый номер телефона в контекст, перемещается к нему, и по возвращении новая (пустая) запись отображается в форме, готовой для заполнения.
Теперь странность
Позиция:
private void btn_NewPosition_Click(object sender, EventArgs e)
{
if (thisPosition != null)
{
DbEntityEntry entry = _fDBC.Entry(thisPosition);
if (entry.State == EntityState.Modified)
{
// PROMPT to save or cancel current, modified record.
}
}
EmployeePosition newPos = new EmployeePosition();
newPos.EmployeeID = thisEmployee.EmployeeID;
newPos.StartDate = DateTime.Today;
try
{
_fDBC.EmployeePositions.Add(newPos);
// INITIALIZING the Validation checklist here
}
catch (DuplicateKeyException ex)
{
// Not getting any exceptions
}
bs_EmployeePos.MoveLast(); // This Code does NOT work.
// The bindingsource does NOT see the new record, the move has no effect,
// and the current (existing) record is displayed on the form.
thisPosition = newPos;
}
Этот код создает новую запись, это можно увидеть в отладчике.Bindingsource просто не видит его.
Вопрос в том, «Почему один работает, а другой нет?»
Опять же, единственное различие между этими обработчиками - это запрос LINQ в телефоне.Числовой обработчик для поиска значения субиндекса для новой записи.Этот запрос происходит (очевидно) до инструкции ADD.
Я могу обойти эту проблему, переопределив источник данных Position Bindingsource непосредственно перед перемещением:
bs_EmployeePos.DataSource = thisEmployee.EmployeePositions.Where(ep => ep.EndDate == null).ToList();
Но это вызывает другие проблемы - мешает успешной работе моего обработчика кнопки [Отмена].
Есть идеи?
Спасибо.Росс
Дополнение: определение EmployeePhoneNumber & EmployeePosition:
public partial class EmployeePosition
{
public int EmployeePositionID { get; set; }
public int PositionID { get; set; }
public int EmployeeID { get; set; }
[Column(TypeName = "date")]
public DateTime StartDate { get; set; }
public int PayrollClassID { get; set; }
public int? InterviewerID { get; set; }
public int? AssignedWorkstationID { get; set; }
[Column(TypeName = "date")]
public DateTime? EndDate { get; set; }
public decimal FTE { get; set; }
[Column(TypeName = "tinyint")]
public Byte? EmployeeRCD { get; set; } // ADD
public virtual WorkStation WorkStation { get; set; }
public virtual Employee Employee { get; set; }
public virtual PayrollClass PayrollClass { get; set; }
public virtual Position Position { get; set; }
}
public partial class EmployeePhoneNumber
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int EmployeeID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int EmployeePhoneNumberID { get; set; }
public int PhoneNumberTypeID { get; set; }
[Required]
[StringLength(3)]
public string AreaCode { get; set; }
[Required]
[StringLength(8)]
public string PhoneNumber { get; set; }
[StringLength(7)]
public string PhoneExtention { get; set; }
[StringLength(25)]
public string PhoneNumberNote { get; set; }
public virtual Employee Employee { get; set; }
public virtual LU_PhoneNumberTypes LU_PhoneNumberTypes { get; set; }
}