Dapper постоянно возвращает значение по умолчанию вместо идентификатора. В чем может быть проблема и как ее исправить? (Дэппер + PostgreSQL)
Можете ли вы объяснить мне, в чем проблема?
public async Task<Appointment?> GetByIdWithPatientAndDoctorAsync(Guid id)
{
await using var connection = new NpgsqlConnection(connectionString);
await connection.OpenAsync();
const string query = """
select a.*,
p.*,
d.*,
c.*,
s.name as specializationname
from
appointments a
inner join
patients p on a.patientid = p.id
inner join
doctors d on a.doctorid = d.id
inner join
clinics c on a.clinicid = c.id
inner join
specializations s on d.specializationid = s.id
where
a.id = @Id
""";
var appointments = await connection.QueryAsync<Appointment, Patient, Doctor, Clinic, Specialization, Appointment>(
query,
(appointment, patient, doctor, clinic, specialization) =>
{
appointment.Patient = patient;
doctor.Specialization = specialization;
appointment.Doctor = doctor;
appointment.Clinic = clinic;
return appointment;
},
new { Id = id },
splitOn: "id, id, id, specializationname");
return appointments.FirstOrDefault();
}
public class Appointment : Entity
{
public Appointment() {}
public Appointment(DateTime date, Guid patientId, Guid doctorId, Guid clinicId, AppointmentStatus appointmentStatus)
{
Date = date;
PatientId = patientId;
DoctorId = doctorId;
ClinicId = clinicId;
AppointmentStatus = appointmentStatus;
}
public DateTime Date { get; set; }
public Guid PatientId { get; set; }
public Patient Patient { get; set; }
public Guid DoctorId { get; set; }
public Doctor Doctor { get; set; }
public Guid ClinicId { get; set; }
public Clinic Clinic { get; set; }
public AppointmentStatus AppointmentStatus { get; set; }
}
public abstract class Entity
{
protected Entity() {}
protected Entity(Guid id)
{
Id = id;
}
public Guid Id { get; }
}
Я уже пробовал играть с splitOn
и вводить ID на другое имя, ничего не помогло.
Dapper всегда использует только сеттеры?
я понял, спасибо, я думал, что щеголь может использовать конструкторы
Dapper может использовать конструктор, но проблема в том, что я не вижу ни одного вашего кода в конструкторе с параметром, который вызывает базовый конструктор и присваивает значение Id
. Кроме того, поскольку вы используете конструктор без параметров в классе Appointment
, по умолчанию Dapper будет использовать конструктор без параметров для привязки значения к экземпляру.
Вы можете использовать конструктор с параметрами, но это будет сложно, поскольку вам нужно убедиться, что параметры вашего конструктора совпадают по имени и последовательности со столбцами, возвращаемыми из вашего запроса. Обратите внимание, что ваш запрос возвращает все столбцы из таблиц, поэтому у вас будет несколько столбцов Id
из разных таблиц. Это будет сложно, когда вы попытаетесь реализовать конструктор (параметров), вы не можете иметь одно и то же имя переменной. Если только в вашем запросе вы явно не указали уникальное имя столбца (пример: ClinicId) вместо Id
. Таким образом, ваш запрос должен возвращать только необходимые столбцы.
Используйте изящный фургон private set
или init
, если не хотите, чтобы диван был публичным.
Как упоминалось в комментарии, в классе Entity
свойство Id
не содержит установщика. Таким образом, ему не присвоено значение, как по умолчанию Guid.Empty
.
Добавление установщика должно решить проблему.
public abstract class Entity
{
protected Entity() {}
protected Entity(Guid id)
{
Id = id;
}
public Guid Id { get; set; }
}
Я сомневаюсь, что ваш класс
Entity
можно скомпилировать. Вы присваиваете значение идентификатора в конструкторе, но ваше свойствоId
не имеет установщика.