簡體   English   中英

在 EF Core 中為實體添加數據期間更新相關實體數據

[英]Update related entities data during adding data for an entity in EF Core

我有兩個實體PayrollEntries具有一對多關系。 多個條目可以與工資單相關聯。 基本上,在新的工資單創建期間,條目需要與PayrollId相關聯,為此我編寫了下面提到的代碼來實現單個SaveChanges()中的全部更改。

Payroll實體:

public class Payroll : BaseEntity, ITrackCreated, ITrackUpdated
{
    public int PayrollId { get; set; }
    public string Name { get; set; }
    public PayrollStatus Status { get; set; }
    public decimal Amount { get; set; }
    public List<Entries> Entries {get;set;}
}

Entries實體:

public class Entries : BaseEntity, ITrackCreated, ITrackUpdated
{
   public int EntryId { get; set; }
   public EntryType EntryType { get; set; }
   public DateTime EntryDate { get; set; }
   public Decimal Amount { get; set; }
   public EntryStatus Status { get; set; }
   public int? PayrollId { get; set; }
   public virtual Payroll Payroll {get;set;}
}

實體關系:

public EntriesConfiguration(ModelBuilder modelBuilder) : base(modelBuilder)
{
    base.Configure();
    Builder.HasKey(t => t.EntryId);
    Builder.Property(p => p.EntryId).ValueGeneratedOnAdd();
    Builder.HasOne(x => x.Payroll).WithMany(x => x.Entries).HasForeignKey(x => x.PayrollId);
    Builder.ToTable("Entries");
}

工資單創建和payrollId更新條目的代碼:

foreach (var entryGroup in groups)
{
   var creditEntries = await _commonDbFunction.GetCreditEntries(entryGroup, EntryStatus.Pending);
   var debitEntries = await _commonDbFunction.GetDebitEntries(entryGroup, EntryStatus.Pending);
   exceptionPayrollDetail = CreatePayroll(payrollDetail); 
   // binding data in payroll entity model

   await _applicationDbContext.Payrolls.AddAsync(exceptionPayrollDetail);

   creditEntries?.ForEach(x => x.PayrollId = exceptionPayrollDetail?.PayrollId); 
   //updating payrollId of above model in Entries Table

   debitEntries?.ForEach(x => x.PayrollId = exceptionPayrollDetail?.PayrollId);
   //updating payrollId of above model in Entries Table

   await _applicationDbContext.SaveChangesAsync(); 
   // calling single SaveChanges adding payroll and updating enries.
}

請建議在單個SaveChanges()中實現相同的方法,因為 0 PayrollId不允許將數據保存在Entries表中,並且在更新條目時payrollId應該大於零。

提前致謝..

由於exceptionPayrollDetail尚未持久化到數據庫,因此exceptionPayrollDetail?.PayrollId將始終為零。

可能你可以在await _applicationDbContext.Payrolls.AddAsync(exceptionPayrollDetail);之后調用SaveChangesAsync() ); ,那么這將生成PayrollId

如果需要,您可以設置導航屬性本身,而不是 id。

稍微簡化的例子:

public class ApplicationContext : DbContext
{
    public DbSet<Entries> Entries { get; set; }
    public DbSet<Payroll> Payrolls { get; set; }
    public string DbPath { get; }

    public ApplicationContext()
    {
        DbPath = System.IO.Path.Join(@"D:\Work\Envisability\EFCorePlayground\EFCorePlayground", "blogging.db");
    }

    protected override void OnConfiguring(DbContextOptionsBuilder options)
    {
        options.UseSqlite($"Data Source={DbPath}");
        //options.LogTo(Console.WriteLine);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        var entriesBuilder = modelBuilder.Entity<Entries>();
        entriesBuilder.Property(p => p.EntryId).ValueGeneratedOnAdd();
        entriesBuilder.HasOne(x => x.Payroll).WithMany(x => x.Entries).HasForeignKey(x => x.PayrollId);
        entriesBuilder.HasKey(t => t.EntryId);
        entriesBuilder.ToTable("Entries");
    }

    public void Seed()
    {
        if (Entries.Any() || Payrolls.Any()) return;

        var entries = new List<Entries>
        {
            new Entries{ Name="e1" },
            new Entries{ Name="e2" },
            new Entries{ Name="e3" }
        };
        var payrolls = new List<Payroll>
        {
            new Payroll{ Name = "1" },
            new Payroll{ Name = "2" },
        };

        entries[0].Payroll = payrolls[0];
        entries[1].Payroll = payrolls[0];
        entries[2].Payroll = payrolls[1];

        Payrolls.AddRange(payrolls);
        Entries.AddRange(entries);
        SaveChanges();
    }

}

public class Payroll
{
    public int PayrollId { get; set; }
    public string Name { get; set; }
    public List<Entries> Entries { get; set; }
}

public class Entries
{
    public int EntryId { get; set; }
    public string Name { get; set; }
    public int? PayrollId { get; set; }
    public virtual Payroll Payroll { get; set; }
}

看一下上面的 Seed 方法,因為數據庫是新鮮的和空的,所以那里沒有 id。

internal class Program
{
    static void Main(string[] args)
    {
        using (var _dbContext = new ApplicationContext())
        {
            _dbContext.Seed();

            var entries = _dbContext.Entries
                .Select(x => new {Id = x.EntryId, Name = x.Name, PayrollId = x.PayrollId})
                .ToList();
            var payrolls = _dbContext.Payrolls
                .Select(x => new {Id = x.PayrollId, Name = x.Name})
                .ToList();
            Debug.WriteLine(JsonSerializer.Serialize(entries));
            Debug.WriteLine(JsonSerializer.Serialize(payrolls));
        }
    }
}

Output 將

[
  {"Id":1,"Name":"e1","PayrollId":1},
  {"Id":2,"Name":"e2","PayrollId":1},
  {"Id":3,"Name":"e3","PayrollId":2}
]
[
  {"Id":1,"Name":"1"},{"Id":2,"Name":"2"}
]

參考: https://docs.microsoft.com/en-us/ef/core/saving/related-data#adding-a-related-entity

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM