我正在从MVC中的回发进行实体更新:

ControlChartPeriod period = _controlChartPeriodService.Get(request.PeriodId);

if (period != null)
{
    SerializableStringDictionary dict = new SerializableStringDictionary();

    dict.Add("lambda", request.Lambda.ToString());
    dict.Add("h", request.h.ToString());
    dict.Add("k", request.k.ToString());

    period.Parameters = dict.ToXmlString();

    // ToDo : fails on save every now and then when one of the values changes; fails on Foreign Key being null
    try
    {
        _controlChartPeriodService.Update(period, request.PeriodId);
        return Ok(request);
    }

更新方法如下所示:
public TObject Update(TObject updated, TKey key)
{
    if (updated == null)
        return null;

    TObject existing = _context.Set<TObject>().Find(key);
    if (existing != null)
    {
        _context.Entry(existing).CurrentValues.SetValues(updated);
        _context.SaveChanges();
    }
    return existing;
}

public TObject Get(TKey id)
{
    return _context.Set<TObject>().Find(id);
}

奇怪的是,我第一次运行它通常效果很好;如果我第二次发回它不起作用,并且由于外键的EntityValidation错误而失败;但是,检查实体时,外键看起来很好并且未被使用。

我是否需要以某种方式同步上下文?

我一直在尝试寻找何时成功或何时不成功的差异。

我正在使用注入(inject)的存储库:
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped((_) => new DataContext(ConfigSettings.Database.ConnectionString));
    services.AddScoped<ControlChartPeriodService, ControlChartPeriodService>();
}

- 更新:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public virtual ICollection<ControlChartPoint> ControlChartPoints { get; set; }

[Required]
public virtual ControlChart ControlChart { get; set; }
public string Parameters { get; set; }

在ControlChartMap中,我们具有以下内容:
HasMany(x => x.Periods)
    .WithRequired(c => c.ControlChart);

最佳答案

如果您期望TObject的加载也包含该关系,那么在我看来,您的问题出在这一行:

TObject existing = _context.Set<TObject>().Find(key);

Find将仅加载TObject记录,而不加载其关系,并且由于代码中没有对ControlChart属性的显式引用,因此它不会延迟加载-这似乎是您期望的行为,所以我m假设您启用了延迟加载

关系已被配置为的事实
HasMany(x => x.Periods).WithRequired(c => c.ControlChart);

指示TObject的ControlChart属性是一组相关的Periods,但这并不意味着它在加载TObject时将强制延迟加载关系。

(我个人试图避免由于这种情况而导致对延迟加载的依赖,而是更喜欢实际上将其禁用,并希望通过使用Load来通过Include或以较小的方式通过一种显式load来积极地加载关系。关于个人品味的问题,但我发现这种方法可以使您免于很多头痛)

因此,如果启用了延迟加载并且喜欢它的工作方式,请在加载之间和保存之前的任何时间引用ControlChart属性,例如
var chart= existing.ControlChart;

或类似的东西

或用于非延迟加载方案,尽管它可以在任何情况下使用:
 TObject existing = _context.Set<TObject>().Where(x=>x.Id==key).Include(x=> x.ControlChart).FirstOrDefault();

09-25 21:17