У меня есть TaskFlowTemplate , довольно стандартный, но немного сложный. Наши пользователи будут иметь возможность работать локально в памяти без необходимости сохранять после каждых изменений. Мой основной ключ - 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 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 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
}
< /code>
Я получаю свои данные, как это, и выполняю сглаженные задачи: < /p>
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);
< /code>
Я изменяю задачи, чтобы быть похожими на модель дерева вместо локально, потому что у меня будет возможность создавать и связывать родительские /дочерние задачи без необходимости сохранять каждый раз. < /p>
public List BuildTaskTree(List 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();
parent.ChildTasks.Add(task);
}
}
// Rotnoder = de utan parent
return flatTasks.Where(t => !t.ParentTaskEntityId.HasValue).ToList();
}
А затем я прохожу каждую активность и устанавливаю их предшественник .
Это работает в памяти, как и должно. Структура данных кажется в порядке при отправке на мой метод обновления. Я ищу и использую модели GPT, но застрял. Я предполагаю, что моя самая большая проблема заключается в том, что ActivityDependency .
Есть ли кто-то, кто может указать мне на правильное направление для обработки такого случая сохранения/обновления?public async Task 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);
< /code>
....
Так что в более простых случаях я загружаю сущность из DB, а затем, как и выше ... а затем Savechanges ... но это не работает здесь ... Я понятия не имею, как я должен идти, чтобы справиться, создавать, обновлять данные в этом дереве. Английский) < /p>
public async Task UpdateTaskFlowTemplate(TaskFlowTemplate updatedTemplate)
{
if (updatedTemplate == null)
throw new ArgumentNullException(nameof(updatedTemplate));
using var db = _dbContextFactory.CreateDbContext();
TaskFlowTemplate existing = null;
if (updatedTemplate.Id != 0)
{
// 10 Retrieve existing template with Tasks + Activities + Suppliers
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 == updatedTemplate.Id);
if (existing == null)
throw new InvalidOperationException($"TaskFlowTemplate with Id {updatedTemplate.Id} not found.");
}
// 20 Update template properties
if (existing != null)
{
db.Entry(existing).CurrentValues.SetValues(updatedTemplate);
}
else
{
existing = updatedTemplate;
db.Add(existing);
}
// 30 Keep track of which Tasks remain (based on Id)
HashSet updatedIds = new HashSet();
// 40 Sync Tasks + Activity + Supplier (without ActivityDependencies)
SyncTasks(existing.Tasks, updatedTemplate.Tasks, db, updatedIds);
// 50 Now we have a complete list of all Tasks that should exist
DeleteMissingTasks(existing.Tasks, updatedIds, db);
// 60 Save Tasks + Activities + Supplier to get Ids for new objects
await db.SaveChangesAsync();
// 70 Handle ActivityDependencies now that all Ids exist
SyncActivityDependencies(existing.Tasks, updatedTemplate.Tasks, db);
// 80 TaskFlowTemplate, set TaskEntity.TaskEntityTemplateId for all Tasks that are templates
foreach (var task in existing.Tasks)
{
if (task.Id != 0)
{
task.TaskEntityTemplateId = task.Id;
task.TaskFlowTemplateId = existing.Id;
task.IsTemplate = true;
db.Entry(task).State = EntityState.Modified;
}
}
// 90 Save ActivityDependencies
await db.SaveChangesAsync();
// Keep only root-level Tasks in TaskFlowTemplate.Tasks
existing.Tasks = existing.Tasks
.Where(t => t.ParentTaskEntityId == null)
.ToList();
return existing;
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... ee-of-data
EF Core, работаю локально, сохраняет/обновляет все дерево данных ⇐ C#
Место общения программистов C#
-
Anonymous
1758093434
Anonymous
У меня есть TaskFlowTemplate , довольно стандартный, но немного сложный. Наши пользователи будут иметь возможность работать локально в памяти без необходимости сохранять после каждых изменений. Мой основной ключ - 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 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 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
}
< /code>
Я получаю свои данные, как это, и выполняю сглаженные задачи: < /p>
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);
< /code>
Я изменяю задачи, чтобы быть похожими на модель дерева вместо локально, потому что у меня будет возможность создавать и связывать родительские /дочерние задачи без необходимости сохранять каждый раз. < /p>
public List BuildTaskTree(List 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();
parent.ChildTasks.Add(task);
}
}
// Rotnoder = de utan parent
return flatTasks.Where(t => !t.ParentTaskEntityId.HasValue).ToList();
}
А затем я прохожу каждую активность и устанавливаю их предшественник .
Это работает в памяти, как и должно. Структура данных кажется в порядке при отправке на мой метод обновления. Я ищу и использую модели GPT, но застрял. Я предполагаю, что моя самая большая проблема заключается в том, что ActivityDependency .
Есть ли кто-то, кто может указать мне на правильное направление для обработки такого случая сохранения/обновления?public async Task 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);
< /code>
....
Так что в более простых случаях я загружаю сущность из DB, а затем, как и выше ... а затем Savechanges ... но это не работает здесь ... Я понятия не имею, как я должен идти, чтобы справиться, создавать, обновлять данные в этом дереве. Английский) < /p>
public async Task UpdateTaskFlowTemplate(TaskFlowTemplate updatedTemplate)
{
if (updatedTemplate == null)
throw new ArgumentNullException(nameof(updatedTemplate));
using var db = _dbContextFactory.CreateDbContext();
TaskFlowTemplate existing = null;
if (updatedTemplate.Id != 0)
{
// 10 Retrieve existing template with Tasks + Activities + Suppliers
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 == updatedTemplate.Id);
if (existing == null)
throw new InvalidOperationException($"TaskFlowTemplate with Id {updatedTemplate.Id} not found.");
}
// 20 Update template properties
if (existing != null)
{
db.Entry(existing).CurrentValues.SetValues(updatedTemplate);
}
else
{
existing = updatedTemplate;
db.Add(existing);
}
// 30 Keep track of which Tasks remain (based on Id)
HashSet updatedIds = new HashSet();
// 40 Sync Tasks + Activity + Supplier (without ActivityDependencies)
SyncTasks(existing.Tasks, updatedTemplate.Tasks, db, updatedIds);
// 50 Now we have a complete list of all Tasks that should exist
DeleteMissingTasks(existing.Tasks, updatedIds, db);
// 60 Save Tasks + Activities + Supplier to get Ids for new objects
await db.SaveChangesAsync();
// 70 Handle ActivityDependencies now that all Ids exist
SyncActivityDependencies(existing.Tasks, updatedTemplate.Tasks, db);
// 80 TaskFlowTemplate, set TaskEntity.TaskEntityTemplateId for all Tasks that are templates
foreach (var task in existing.Tasks)
{
if (task.Id != 0)
{
task.TaskEntityTemplateId = task.Id;
task.TaskFlowTemplateId = existing.Id;
task.IsTemplate = true;
db.Entry(task).State = EntityState.Modified;
}
}
// 90 Save ActivityDependencies
await db.SaveChangesAsync();
// Keep only root-level Tasks in TaskFlowTemplate.Tasks
existing.Tasks = existing.Tasks
.Where(t => t.ParentTaskEntityId == null)
.ToList();
return existing;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79761990/ef-core-work-locally-save-update-entire-tree-of-data[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия