首页 > 解决方案 > 关于简化功能的建议

问题描述

我有一个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)为真时,我需要将当前值更新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()。为什么?

我可以简化这段代码吗?

更新:

根据回答Henk Holterman和我的代码private void Update(Contracts c)

从 更改值GetMainValues(),但没有从GetDetailValues()

标签: c#entity-frameworkentity-framework-corecrud

解决方案


我添加到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();
    }
}

推荐阅读