Советы по упрощению функций - PullRequest
0 голосов
/ 04 июля 2019

У меня есть сущность Contracts, как это:

public partial class Contracts
{
    public Contracts()
    {
        ListKindWorks = new HashSet<ListKindWorks>();
        ListSubjects = new HashSet<ListSubjects>();
    }

    public int Id { get; set; }
    public string Num { get; set; }
    public DateTime DateConclusion { get; set; }
    public int Worker { get; set; }
    public DateTime DateStartWork { get; set; }
    public DateTime DateEndWork { get; set; }
    public float Salary { get; set; }

    public virtual Workers WorkerNavigation { get; set; }
    public virtual ICollection<ListKindWorks> ListKindWorks { get; set; }
    public virtual ICollection<ListSubjects> ListSubjects { get; set; }   
}

И функция ShowUpdateDialog():

/// <summary>
/// Open dialog for update chosen Contract
/// </summary>
/// <param name="c">chosen Contract</param>
internal void ShowUpdateDialog(Contracts c)
{
    Contract = c;
    using (ContractForm form = new ContractForm())
    {
        form.Fill(model.Data);
        form.Fill(Contract);
        form.Fill(model.GetUI(Mode.UPDATE));
        if (form.ShowDialog() == DialogResult.OK)
        {
            bool result = true;
            try
            {
                using (ModelContext context = new ModelContext())
                {
                    context.Attach(Contract);
                    Contract = form.GetMainValues(Contract);
                    Contract = form.GetDetailValues(Contract);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                result = false;
                string msg = string.Format("Ошибка во время обновления записи в базе данных. Детали: {0}", ex.Message);
                form.ShowError(msg);
            }

            if (result)
            {
                ContractUpdatedSuccessEvent?.Invoke(this, EventArgs.Empty);
            }
        }
    }
}

Внешняя переменная:

public Contracts Contract { get; set; }

Этоиспользуется для того, чтобы не выделять память каждый раз, и является общедоступной, поэтому в случае успешного обновления другой класс может взять ее и вставить в DataGridView.Поэтому я не обращаюсь к базе данных для текущих значений записи, потому что данные поступают из DataGridView.Для отслеживания изменений используется context.Attach(Contract).

internal Contracts GetMainValues(Contracts c)
{
    c.Num = tbNum.Text;
    c.Salary = float.Parse(tbSalary.Text);
    c.DateConclusion = dpDateConclusion.Value;
    c.DateStartWork = dpDateStart.Value;
    c.DateEndWork = dpDateEnd.Value;
    Item item = (Item)cbWorker.SelectedItem;
    c.Worker = item.Id;

    return c;
}


internal Contracts GetDetailValues(Contracts c)
{
    listKindWorks.Clear();
    listSelectedSubjects.Clear();

    foreach (int index in clbKindWork.CheckedIndices)
    {
        int id = ((Item)clbKindWork.Items[index]).Id;
        ListKindWorks item = new ListKindWorks
        {
            IdContract = c.Id,
            IdKindWork = id
        };
        listKindWorks.Add(item);
    }
    foreach (Item item in lbSelectedSubject.Items)
    {
        ListSubjects subject = new ListSubjects
        {
            IdContract = c.Id,
            IdSubject = item.Id
        };
        listSelectedSubjects.Add(subject);
    }

    c.ListKindWorks = listKindWorks;
    c.ListSubjects = listSelectedSubjects;

    return c;
}

Моя проблема заключается в следующем:

Когда if (.. == DialogResult.OK) имеет значение true, мне нужно обновить текущий Contractдля новых значений из form, например:

context.Attach(Contract);
Contract = form.GetMainValues(Contract);
Contract = form.GetDetailValues(Contract);
context.SaveChanges();

Но поэтому этот код должен быть в using (ContractForm..).В противном случае невозможно получить новые значения из form.Если я создаю новую переменную, например Contracts, и отдельную функцию Update, например, так:

private void Update(Contracts c)
{
    using (ModelContext context = new ModelContext())
    {
        context.Attach(Contract);
        Contract = c;
        context.SaveChanges();
    }
}

Обновление значений из GetDetailValues() не происходит.Зачем?

Можно ли упростить этот код?

Обновление:

Согласно коду из ответа Хенк Холтерман и мои private void Update(Contracts c):

изменили значения с GetMainValues(), но не с GetDetailValues()

1 Ответ

0 голосов
/ 04 июля 2019

Я добавил к Contracts метод Update() и вызвал его после .Attach()

internal void Update(Contracts c)
{
    this.Num = c.Num;
    this.Salary = c.Salary;
    this.Worker = c.Worker;
    this.FullName = c.FullName;
    this.DateConclusion = c.DateConclusion;
    this.DateStartWork = c.DateStartWork;
    this.DateEndWork = c.DateEndWork;
    this.ListKindWorks = c.ListKindWorks;
    this.ListSubjects = c.ListSubjects;
}

private void Update(Contracts oldValue, Contracts newValue)
{
    using (ModelContext context = new ModelContext())
    {
        context.Attach(oldValue);
        oldValue.Update(newValue);
        // oldValue = newValue; // .Attach does not respond to this
        context.SaveChanges();
    }
}
...