Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

EF Core, Work locally, save/update entire tree of data

$
0
0

I have a TaskFlowTemplate, pretty standard but a bit complex. Our users will have the ability to work locally in memory without need to save after every changes. My primary key is int Id.

public class TaskFlowTemplate {    public int Id { get; set; }   // This is found on every class   [NotMapped]   public Guid Guid { get; set; } = Guid.NewGuid();  // Maybe need this to link som data in memory before we got Id from DB, this one is on every one   // ...   public ICollection<TaskEntity> Tasks { get; set; }}public class TaskEntity{        .......        // one-to-one relation if TaskEntity is an activity        public int? ActivityEntityId { get; set; }        public ActivityEntity Activity { get; set; }}public class ActivityEntity{    ....    public ICollection<ActivityDependency> Dependencies { get; set; }    public TaskEntity Task { get; set; }  // Backref.}public class ActivityDependency{    ...    public int ActivityId { get; set; }    public ActivityEntity Activity { get; set; }    public int PredecessorId { get; set; }    public ActivityEntity Predecessor { get; set; }    [NotMapped]    public Guid PredecessorGuid { get; set; }  // use when link in memory}

I get my data like this and get tasks flattened:

using var db = _dbContextFactory.CreateDbContext();return await db.TaskFlowTemplates        .Include(t => t.Tasks)            .ThenInclude(te => te.Activity)                .ThenInclude(a => a.Dependencies)        .Include(t => t.Tasks)            .ThenInclude(te => te.Supplier)        .FirstOrDefaultAsync(t => t.Id == id);

I change tasks to be like a tree model instead locally because I will have ability to create and link parent / child tasks without the need to save every time.

public List<TaskEntity> BuildTaskTree(List<TaskEntity> flatTasks){    // Indexera alla tasks på Id (eller Guid om du kör med det internt)    var taskLookup = flatTasks.ToDictionary(t => t.Id);    foreach (var task in flatTasks)    {        if (task.ParentTaskEntityId.HasValue && taskLookup.TryGetValue(task.ParentTaskEntityId.Value, out var parent))        {            parent.ChildTasks ??= new List<TaskEntity>();            parent.ChildTasks.Add(task);        }    }    // Rotnoder = de utan parent    return flatTasks.Where(t => !t.ParentTaskEntityId.HasValue).ToList();}

And then I go through every ActivityDependency and set their PredecessorGuid.

This works in memory as it should. Data structure seems ok when sending to my update method.

Now I have problems when I will save/update changes. I've search and use GPT models but I got stuck. I guess my biggest problem are on the ActivityDependency.

Is there someone that could point me on right direction for handle an save/update case like this?

------ EDIT

I use db factory so when I work with data locally it's detached..

public async Task<TaskFlowTemplate> UpdateTaskFlowTemplate(TaskFlowTemplate taskFlowTemplate){using var db = _dbContextFactory.CreateDbContext();            var existing = await db.TaskFlowTemplates                .Include(t => t.Tasks)                    .ThenInclude(te => te.Activity)                        .ThenInclude(a => a.Dependencies)                .Include(t => t.Tasks)                    .ThenInclude(te => te.Supplier)                .FirstOrDefaultAsync(t => t.Id == taskFlowTemplate.Id);db.Entry(existing).CurrentValues.SetValues(taskFlowTemplate);

....

so in simplier case I load entity from db, and then like above... and then SaveChanges... But that doesn't work here... I don't have a clue how I should go on to handle create, remove, update data in this tree.


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>