Я столкнулся с трудностями при попытке сохранить данные тренировки в базе данных с помощью Entity Framework Core и веб-API ASP.NET. У меня есть класс Workout
, определенный с такими свойствами, как WorkoutId
, ExerciseTypeGroups
, CreatorId
, Creator
и Status
. Свойство ExerciseTypeGroups
представляет собой список объектов ExerciseTypeGroup
.
Я реализовал метод CreateAsync
в своем dbContext
, чтобы добавить объект Workout
в базу данных и сохранить изменения с помощью SaveChangesAsync
. Кроме того, у меня есть метод WorkoutManager.CreateAsync
, который сериализует объект Workout
в JSON и отправляет его на конечную точку сервера с помощью HTTP-запроса POST
.
Вот краткое описание ключевых компонентов:
//The command initializing the data entering
public ICommand CompleteWorkoutCommand => new Command(CompleteWorkout);
private async void CompleteWorkout()
{
Workout workout = new Workout();
workout.ExerciseTypeGroups = new List<ExerciseTypeGroup>(ExerciseTypeGroups);
string userIdString = Preferences.Get("UserID", defaultValue: null);
if (int.TryParse(userIdString, out int userId))
{
// If parsing was successful, set the CreatorId property
workout.CreatorId = userId;
workout.Creator = await UserManaging.ReadAsync(userId);
// Create the workout asynchronously
Task.Run(() => WorkoutManager.CreateAsync(workout)).GetAwaiter().GetResult();
}
else
{
// Handle the case where parsing fails
Console.WriteLine("Failed to parse user ID from preferences.");
// You might want to handle this error case appropriately for your application
}
}
// DbContext method to add Workout object to the database
public async Task CreateAsync(Workout item)
{
try
{
dbContext.Workouts.Add(item);
await dbContext.SaveChangesAsync();
}
catch (Exception ex)
{
// Handle exception
throw;
}
}
// Workout class definition
public class Workout
{
[Key]
public int WorkoutId { get; set; }
public List<ExerciseTypeGroup> ExerciseTypeGroups { get; set; }
public int CreatorId { get; set; }
public User Creator { get; set; }
public Status Status { get; set; }
public Workout()
{
ExerciseTypeGroups = new List<ExerciseTypeGroup>();
}
public Workout(User user)
{
Status = Status.Waiting;
Creator = user;
ExerciseTypeGroups = new List<ExerciseTypeGroup>();
}
}
// Manager method to send Workout object to server endpoint
public static async Task CreateAsync(Workout item)
{
try
{
var json = JsonConvert.SerializeObject(item);
var data = new StringContent(json, Encoding.UTF8, "application/json");
var response = await Client._httpClient.PostAsync(Client._url + $"Workout", data);
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request error: {e.Message}");
}
}
// Server-side endpoint in ASP.NET Web API controller
[HttpPost]
public async Task Create([FromBody]Workout item)
{
await _workoutContext.CreateAsync(item);
}
Несмотря на реализацию этих методов, я сталкиваюсь с проблемами, из-за которых данные тренировки не сохраняются в базе данных. Я убедился, что код как на стороне клиента, так и на стороне сервера выполняется без ошибок, но данные не сохраняются в базе данных.
Каковы могут быть возможные причины этой проблемы и как ее устранить и устранить? Любые идеи или предложения будут с благодарностью приняты. Если информации недостаточно вот мой гитхаб https://github.com/danchuu/Muscles_AppDR. Спасибо.
@Dai Я добавил журналирование SQL, и вот ошибка Pastebin.com/sCh3pnBi
Ошибки, указанные в этом скрипте, не соответствуют ошибке в вашем сообщении.
@Dai Ты имеешь в виду, что ошибка где-то еще?
... рискуя показаться бессердечным, похоже, вам нужно научиться пользоваться отладчиком.
Во-первых, существует исключение, поэтому утверждение «серверный код выполняется без ошибок» неверно. Во-вторых, ознакомьтесь с официальной документацией EF Core, посвященной работе с отключенными объектами. public User Creator { get; set; }
вызывает проблему в данном конкретном случае, поскольку dbContext.Add
помечает объект и все связанные с ним объекты для создания. Но в вашем случае User
не нов. Есть способы решить эту проблему, но ни один из них не является универсальным. В общем, либо не отправляйте объект Creator
, просто CreatorId
, либо Attach
Creator
перед вызовом Add
.
@dancho Ваш подход совершенно неправильный. Сначала попробуйте научиться правильно использовать EF Core
entityframeworktutorial.net/efcore/entity-framework-core.aspx
@DarkkL можешь поподробнее?
@IvanStoev Я рассмотрю это, но не думаю, что это моя текущая проблема. Я пробовал использовать только CreatorID, но не получилось. У вас есть другая идея?
Проблема заключалась в том, что я давал значение null для столбца, не допускающего значения NULL, в базе данных.
Удалите свой
catch (Exception ex)
, потому что он не приносит никакой пользы. Что вы видите в своем отладчике? Добавьте ведение журнала SQL, чтобы вы могли видеть фактически генерируемый SQL. Используйте инструменты трассировки или профилирования вашей СУБД, чтобы увидеть, что происходит. Вы подключаетесь к нужному экземпляру базы данных? Вы используете MSSQL, MySQL/MariaDb, Postgres? И т. д?