System.InvalidOperationException происходит в моем приложении WPFC#

Место общения программистов C#
Ответить
Anonymous
 System.InvalidOperationException происходит в моем приложении WPF

Сообщение Anonymous »

Я пишу приложение WPF по шаблону MVVM. На мой взгляд, у меня есть DataGrid. У меня также есть 4 текстовых поля, 1 поле со списком и кнопка для добавления нового объекта в DataGrid. Для обработки данных я использую Entity Framework Core.
Вот поле со списком: Рабочий класс:

Код: Выделить всё

public class Worker : ObservableObject
{
private int _id;
private string _name;
private string _secondName;
private int _age;
private string _email;
private List _jobTitles;

private int _jobTitleId;
private JobTitle? _jobTitle;

public int Id
{
get => _id;
set => Set(ref _id, value);
}

public string Name
{
get => _name;
set => Set(ref _name, value);
}

[NotMapped]
public List JobTitles
{
get => _jobTitles;
set => Set(ref _jobTitles, value);
}

public int JobTitleId
{
get => _jobTitleId;
set => Set(ref _jobTitleId, value);
}

public JobTitle? JobTitle
{
get => _jobTitle;
set => Set(ref _jobTitle, value);
}
}

Код: Выделить всё

JobTitle
класс:

Код: Выделить всё

public class JobTitle : ObservableObject
{
private int _id;
private string _title;
private ObservableCollection _workers;

public int Id
{
get => _id;
set => Set(ref _id, value);
}

public string Title
{
get => _title;
set => Set(ref _title, value);
}

public ObservableCollection Workers
{
get => _workers;
set => Set(ref _workers, value);
}

public override bool Equals(object? obj)
{
return (obj==null || obj is not JobTitle) ? false : Title == (obj as JobTitle).Title;
}

public override int GetHashCode()
{
return Title.GetHashCode();
}
}
Просмотр модели для просмотра с помощью поля со списком:

Код: Выделить всё

public class WorkersDataTableVM : ObservableObject
{
private WorkerRepository _workerRepository;
private JobTitleRepository _jobTitleRepository;
private ObservableCollection _workers;
private Worker _newWorker;

public ObservableCollection Workers
{
get => _workers;
set => Set(ref _workers, value);
}

public Worker NewWorker
{
get => _newWorker;
set => Set(ref _newWorker, value);
}

public RelayCommand AddWorkerCommand { get; set; }

public WorkersDataTableVM()
{
_workerRepository = new WorkerRepository();
_jobTitleRepository = new JobTitleRepository();
Workers = new ObservableCollection(_workerRepository.GetAllWorkers());
NewWorker = new Worker();
LoadData();
AddWorkerCommand = new RelayCommand(AddWorker,CanAddWorker);
}

private bool CanAddWorker(object arg)
{
bool flag = false;

if (NewWorker.Name != default(string) && NewWorker.SecondName != default(string) && NewWorker.Age != default(int) &&  NewWorker.JobTitleId != default(int))
{
flag = true;
}

return flag;
}

private void AddWorker(object obj)
{
Workers.Add(NewWorker);
_workerRepository.AddWorker(NewWorker);
NewWorker = new();
}

private void LoadData()
{
var workers = _workerRepository.GetAllWorkers();
var jobTitle = _jobTitleRepository.GetAllJopTitles();
Workers = new ObservableCollection(workers);

foreach (Worker worker in Workers)
{
worker.JobTitles = jobTitle;
}

NewWorker.JobTitles = jobTitle;
}
}
Я не понимаю, почему я получаю это исключение:

System.InvalidOperationException: экземпляр типа сущности «JobTitle» невозможно отследить, поскольку уже отслеживается другой экземпляр с тем же значением ключа для {'Id'}. При присоединении существующих сущностей убедитесь, что присоединен только один экземпляр сущности с заданным значением ключа. Рассмотрите возможность использования DbContextOptionsBuilder.EnableSensitiveDataLogging, чтобы увидеть конфликтующие значения ключей.

Я написал такое же простое консольное приложение, которое делает то же самое:

Код: Выделить всё

public class User
{
public int Id { get; set; }
public string? Name { get; set; }
[NotMapped]
public List Companies { get; set; }
public int CompanyId { get; set; }
public Company? Company { get; set; }
}

public class Company
{
public int Id { get; set; }
public string? Name { get; set; }

public List Users { get; set; } = new();

public override bool Equals(object? obj)
{
return (obj == null || obj is not Company) ? false : Name == (obj as Company).Name;
}

public override int GetHashCode()
{
return Name.GetHashCode();
}
}

public class Program
{
static void Main(string[] args)
{
using (ApplicationContext db = new ApplicationContext())
{
User user = new User();

user.Companies = db.Companies.ToList();
user.Name = "Name";
user.Company = user.Companies[0];

db.Users.Add(user);
db.SaveChanges();
}
}
}
и эта маленькая программа работает нормально и не генерирует исключений.
PS: я пытался добавить нового Worker, используя свой код в виртуальной машине, но исключение все равно происходит, поэтому я не думаю, что проблема в части XAML.
PS №2: я могу это исправить, если создам нового работника, используя свойство JobTitleId вместо JobTitle , но тогда мне нужно будет добавить конвертеры в поле со списком и так далее.
Обновление. Я понимаю, что моя проблема в том, что я создаю больше в моем репозитории одновременно более одного DbContext, и они
мешают друг другу, поэтому мой НОВЫЙ вопрос, как мне это исправить:
  • Следует ли мне создать один общий DbContext для всех репозиториев, которые будут существовать на протяжении всего жизненного цикла приложения
  • Или мне следует создавать новый DbContext каждый раз, когда мне нужно выполнить операцию CRUD?
Какой способ более подходит в контексте WPF и MVVM?


Подробнее здесь: https://stackoverflow.com/questions/783 ... pplication
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»