实体框架在子插入后不保存导航属性

时间:2021-01-11 23:09:32

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

我有两个相关实体,一个事件和一个报告(一对多)。 事件将始终首先添加。 报告将在添加事件后添加,但绝不会同时添加。 报告更改跟踪实体在插入后显示正确的导航关系。 但是当我再次加载报告或事件时,没有存储任何关系。

知道我做错了什么或遗漏了什么吗?

事件模型类(缩短):

public class Incident
{         
    public int Id { get; private set; }              
    public byte[] RowVersion { get; private set; }        
    public string UniqueId { get; set; }
    public ICollection<Report> Reports { get; private set; } = new HashSet<Report>();         
}

报表模型类(缩短):

public class Report
{ 
    public int Id { get; private set; }              
    public byte[] RowVersion { get; private set; }         
    public Incident Incident { get; set; }
    public string UniqueId { get; set; }
}

事件配置:

internal class IncidentConfiguration : IEntityTypeConfiguration<Incident>
{
    internal static IncidentConfiguration Create() => new IncidentConfiguration();
    public void Configure(EntityTypeBuilder<Incident> builder)
    {
        builder
            .Property(incident => incident.Id)
            .ValueGeneratedOnAdd();
        builder
            .Property(incident => incident.RowVersion)
            .IsConcurrencyToken();
    }
}

报表配置:

internal class ReportConfiguration : IEntityTypeConfiguration<Report>
{
    internal static ReportConfiguration Create() => new ReportConfiguration();
    public void Configure(EntityTypeBuilder<Report> builder)
    {
        builder
            .Property(report => report.Id)
            .ValueGeneratedOnAdd();
        builder
            .Property(report => report.RowVersion)
            .IsConcurrencyToken();            
        builder
            .HasOne(report => report.Incident)
            .WithMany(incident => incident.Reports)
            .HasForeignKey(report => report.UniqueId)
            .HasPrincipalKey(incident => incident.UniqueId)
            .OnDelete(DeleteBehavior.Cascade);
    }
}

添加事件的方法:

public async ValueTask<EntityEntry<Common.Models.Incident>> AddAsync(Common.Models.Incident incident)
    {
        EntityEntry<Common.Models.Incident> entity = null;
        _manualResetEvent.WaitOne();
        try
        {
            using var context = new IncidentManagerContext(_connectionString);
            entity = await context.Incidents.AddAsync(incident);
            await context.SaveChangesAsync();
        }
        catch (Exception) { entity = null; }
        finally { _manualResetEvent.Set(); }
        return entity;
    }

添加报表的方法:

public async ValueTask<EntityEntry<Common.Models.Report>> AddAsync(Common.Models.Report report)
    {
        EntityEntry<Common.Models.Report> entity = null;
        if (!string.IsNullOrEmpty(report.UniqueId))
        {
            _manualResetEvent.WaitOne();
            try
            {
                using var context = new IncidentManagerContext(_connectionString);
                entity = await context.AddAsync(report);
                await context.SaveChangesAsync();
            }
            catch (Exception) { entity = null; }
            finally { _manualResetEvent.Set(); }
        }
        return entity;
    }

1 个答案:

答案 0 :(得分:0)

最后我发现了问题,不是异步的东西,也不是缺少的手动分配。这只是加载端缺少的扩展方法 IncludeThenInclude...

public async Task<Common.Models.Incident> GetByUniqueIdAsync(string uniqueId)
    {
        Common.Models.Incident incident = null;
        _manualResetEvent.WaitOne();
        try
        {
            using var context = new IncidentManagerContext(_connectionString);
            incident = await context.Incidents
                .Include(incident => incident.Reports)
                .ThenInclude(reports => reports.DetailReports)
                .Where(i => i.UniqueId == uniqueId)
                .SingleAsync();
        }
        catch (Exception) { }
        finally { _manualResetEvent.Set(); }
        return incident;
    }