// 查找现有预约并修改描述 var existingAppointment = Data.Appointments.FirstOrDefault(a => a.Patient == this && a.Doctor == Doctor); 明明存在数据,为什么没有查找出来
C#中关于linq查询==和equal的区别 原理
==运算符:- 用于比较两个对象的引用(对于引用类型)或值(对于值类型)。
- 默认情况下,引用类型使用引用比较,但可以重载
==运算符进行自定义比较。
Equals方法:- 是一个方法,默认实现比较对象的引用,但可以在类中重写以实现自定义比较逻辑。
- 通常用于比较对象内容而非引用。
解决方法:
1. 对象比较问题
在 C# 中,FirstOrDefault 会逐个比较集合中的对象。如果 a.Patient == this 和 a.Doctor == Doctor 不能正确返回 true,即使两个对象看起来相同,但它们实际上可能是两个不同的对象(即使它们的字段值相同),这可能是对象比较的问题。
解决方案:重写 Equals 和 GetHashCode
你需要确保 Appointment 类的 Patient 和 Doctor 对象的比较是基于值,而不是基于引用。默认情况下,C# 的 == 运算符比较的是对象的引用,而不是它们的内容。因此你可以重写 Equals 和 GetHashCode 方法,以便通过值来进行比较。
例如,在 Doctor 和 Patient 类中,重写这些方法:
public class Doctor
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
public override bool Equals(object obj)
{
if (obj is Doctor other)
{
return FirstName == other.FirstName && LastName == other.LastName && Email == other.Email;
}
return false;
}
public override int GetHashCode()
{
return HashCode.Combine(FirstName, LastName, Email);
}
}
public class Patient
{
public string FirstName { get; set; }
public string LastName { get; set; }
// 其他属性
public override bool Equals(object obj)
{
if (obj is Patient other)
{
return FirstName == other.FirstName && LastName == other.LastName;
}
return false;
}
public override int GetHashCode()
{
return HashCode.Combine(FirstName, LastName);
}
}
2. 对象的引用不同
即使两个对象看起来相同,它们在内存中的引用可能不同。例如,this 可能指向的是一个当前实例,而集合中的对象可能是通过反序列化或其他方式创建的,这样它们的引用就会不同。
解决方案:基于 ID 或唯一标识符查找
一种常见的做法是为 Patient 和 Doctor 以及 Appointment 类添加唯一标识符,比如 ID,然后通过 ID 进行比较。
public class Doctor
{
public int Id { get; set; } // 唯一标识符
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
public class Patient
{
public int Id { get; set; } // 唯一标识符
public string FirstName { get; set; }
public string LastName { get; set; }
}
// 查找时,基于 ID 进行查找,而不是比较对象
var existingAppointment = Data.Appointments.FirstOrDefault(a => a.Patient.Id == this.Id && a.Doctor.Id == Doctor.Id);