更新子表添加记录而不是修改现有记录

时间:2021-05-11 20:48:32

标签: c# .net entity-framework-core

我有这两个模型:

public class Balance1 : IAnalyticsSection
{
    public int Id { get; set; }
    public Guid DataFileId { get; set; }

    public string Side { get; set; }
    public decimal AverageHSway { get; set; }
    public decimal AverageSSpeed { get; set; }
    public decimal AverageLHSway { get; set; }
    public decimal AverageRHSway { get; set; }
    public decimal PercentAverageInLSphere { get; set; }
    public decimal PercentAverageInRSphere { get; set; }
    public decimal AverageTotalSway { get; set; }

    public virtual ICollection<Balance1Part> Parts { get; set; } = new List<Balance1Part>();
    public virtual DataFile DataFile { get; set; }
}


public class Balance1Part
{
    public int Id { get; set; }
    public int Balance1Id { get; set; }

    public int Order { get; set; }
    public decimal ConvexHullArea { get; set; }
    public decimal HSway { get; set; }
    public decimal SSpeeds { get; set; }
    public decimal LHSway { get; set; }
    public decimal RHSway { get; set; }
    public decimal PercentInLSphere { get; set; }
    public decimal PercentInRSphere { get; set; }
    public decimal TotalSway { get; set; }
        
    public virtual Balance1 Balance1 { get; set; }
}

在我的上下文中,我有 public DbSet<Balance1> Balance1 { get; set; } 但没有 Balance1Part。每个 Balance1Part 永远只有 5 个 Balance1 记录。当我在 Balance1 中输入一条新记录时,它成功地创建了 5 个部分中的每一个。如果我尝试更新 Balance1,它会成功,但会创建 5 个额外的零件记录。这些是现有记录的副本。

这是输入/更新我的 Balance1Balance1Parts 的代码:

var innerBalance1File = await innerContext.Balance1.SingleOrDefaultAsync(x => x.DataFileId == dataFile.Id);
                            
Balance1Class balance1Class = new Balance1Class();

if (innerBalance1File == null)
{
    innerBalance1File = new Balance1();
    innerBalance1File.DataFileId = dataFile.Id;
    innerBalance1File = balance1Class.Balance1Data(innerBalance1File, values);

    await innerContext.AddAsync(innerBalance1File);
}
else
{
    innerBalance1File = balance1Class.Balance1Data(innerBalance1File, values);
    innerContext.Entry(innerBalance1File).State = EntityState.Modified;
}

await innerContext.SaveChangesAsync();

这是我的Balance1Calss

public class Balance1Class
{
    // create a method that has dataFile and values passed to it, populates the dataFile keys with appropriate values and returns datafile
    public Balance1 Balance1Data(Balance1 balance1, Dictionary<string, object> values)
    {
        //Balance1 balance1 = new Balance1();
        //Balance1Part balance1Part = new Balance1Part();

        if ((values["DataType"]).Equals("Balance1R"))
        {
            balance1.Side = "R";
        }
        else
        {
            balance1.Side = "L";
        }

        balance1.AverageHSway = decimal.Parse(values["AverageHSway"].ToString());
        balance1.AverageLHSway = decimal.Parse(values["AverageLHSway"].ToString());
        balance1.AverageRHSway = decimal.Parse(values["AverageRHSway"].ToString());
        balance1.AverageSSpeed = decimal.Parse(values["AverageSSpeed"].ToString());
        balance1.AverageTotalSway = decimal.Parse(values["AverageTotalSway"].ToString());
        balance1.PercentAverageInLSphere = decimal.Parse(values["%AverageInLSphere"].ToString());
        balance1.PercentAverageInRSphere = decimal.Parse(values["%AverageInRSphere"].ToString());

        for (int i = 1; i < 6; i++)
        {
            Balance1Part balance1Part = new Balance1Part
            {
                HSway = decimal.Parse(values["HSway" + i].ToString()),
                SSpeeds = decimal.Parse(values["SSpeeds" + i].ToString()),
                LHSway = decimal.Parse(values["LHSway" + i].ToString()),
                RHSway = decimal.Parse(values["RHSway" + i].ToString()),
                PercentInLSphere = decimal.Parse(values["%InLSphere" + i].ToString()),
                PercentInRSphere = decimal.Parse(values["%InRSphere" + i].ToString()),
                TotalSway = decimal.Parse(values["TotalSway" + i].ToString()),
                ConvexHullArea = decimal.Parse(values["ConvexHullArea" + i].ToString()),
                Order = i,
            };
            balance1.Parts.Add(balance1Part);
        }

        return balance1;
    }
}

我哪里出错了?

更新

根据 bbelow 的答案,我将 for 更新为:

var balance1Parts = balance1.Parts;  // Gets actual balance parts: returns a list

if (balance1Parts.Count == 0 || balance1Parts == null)
{
    for (int i = 1; i < 6; i++)
    {
        Balance1Part balance1Part = new Balance1Part
        {
            HSway = decimal.Parse(values["HSway" + i].ToString()),
            SSpeeds = decimal.Parse(values["SSpeeds" + i].ToString()),
            LHSway = decimal.Parse(values["LHSway" + i].ToString()),
            RHSway = decimal.Parse(values["RHSway" + i].ToString()),
            PercentInLSphere = decimal.Parse(values["%InLSphere" + i].ToString()),
            PercentInRSphere = decimal.Parse(values["%InRSphere" + i].ToString()),
            TotalSway = decimal.Parse(values["TotalSway" + i].ToString()),
            ConvexHullArea = decimal.Parse(values["ConvexHullArea" + i].ToString()),
            Order = i,
        };
        balance1.Parts.Add(balance1Part);
    }
}
else
{
    foreach (var balance1Part in balance1Parts)
    {
        balance1Part.HSway = decimal.Parse(values["HSway" + balance1Part.Order].ToString());
        balance1Part.SSpeeds = decimal.Parse(values["SSpeeds" + balance1Part.Order].ToString());
        balance1Part.LHSway = decimal.Parse(values["LHSway" + balance1Part.Order].ToString());
        balance1Part.RHSway = decimal.Parse(values["RHSway" + balance1Part.Order].ToString());
        balance1Part.PercentInLeftSphere = decimal.Parse(values["%InLSphere" + balance1Part.Order].ToString());
        balance1Part.PercentInRSphere = decimal.Parse(values["%InRSphere" + balance1Part.Order].ToString());
        balance1Part.TotalSway = decimal.Parse(values["TotalSway" + balance1Part.Order].ToString());
        balance1Part.ConvexHullArea = decimal.Parse(values["ConvexHullArea" + balance1Part.Order].ToString());
        balance1Part.Order = int.Parse(values["Order"].ToString());
        balance1.Parts.Add(balance1Part);
    }
}

它仍然只添加新部件而不是更新现有部件。我认为部件的上下文没有正确更新,因为我第二次运行它时,我希望 innerBalance1File 包含部件,但是当我将其注销时,它并不存在。任何人都可以请告知有什么问题吗?

我应该在这些行之间添加 innerContext.Balance1.Update(innerBalance1File); 吗?

innerBalance1File = balance1Class.Balance1Data(innerBalance1File, values);
innerContext.Entry(innerBalance1File).State = EntityState.Modified;

这似乎不是必须的。

更新

我添加了 innerContext.Balance1.Update(innerBalance1File); 并删除了 innerContext.Entry(innerBalance1File).State = EntityState.Modified; 但得到了相同的结果。我需要在这里使用 Attach 吗?我在考虑 innerContext.Attach(innerBalance1File.Parts); 之前的 innerContext.Balance1.Update(innerBalance1File);

1 个答案:

答案 0 :(得分:0)

以下行执行您所说的:创建 5 个新子项 Balance1Part,然后添加它们。

Balance1Part balance1Part = new Balance1Part

如果你想更新它们,那么你应该用类似的东西替换这个 for 块代码:

var balance1Parts = balance1.Parts;  // Gets actual balance parts: returns a list

if (balance1Parts == null)
{
    // Here the balance parts don't exist yet, so you can keep current code to create them
}
else
{
    // Here the balance parts are already set. 
    // So loop on every balance part and update it.
    // BUT! You'll have to find/set a unique identifier to know which one to update with which data ;)
    foreach (var balancePart in balance1Parts)
    {
        balancePart.HSway = decimal.Parse(values["HSway" + i].ToString());
        balancePart.SSpeeds = decimal.Parse(values["SSpeeds" + i].ToString());
        // ... and so on
    }
}

不要忘记将更改保存在数据库上下文中,您应该会没事的。