// 查找现有预约并修改描述 var existingAppointment = Data.Appointments.FirstOrDefault(a => a.Patient == this && a.Doctor == Doctor); 明明存在数据,为什么没有查找出来

C#中关于linq查询==和equal的区别 原理

  1. == 运算符
    • 用于比较两个对象的引用(对于引用类型)或值(对于值类型)。
    • 默认情况下,引用类型使用引用比较,但可以重载 == 运算符进行自定义比较。
  2. Equals 方法
    • 是一个方法,默认实现比较对象的引用,但可以在类中重写以实现自定义比较逻辑。
    • 通常用于比较对象内容而非引用。

解决方法:

1. 对象比较问题

在 C# 中,FirstOrDefault 会逐个比较集合中的对象。如果 a.Patient == thisa.Doctor == Doctor 不能正确返回 true,即使两个对象看起来相同,但它们实际上可能是两个不同的对象(即使它们的字段值相同),这可能是对象比较的问题。

解决方案:重写 EqualsGetHashCode

你需要确保 Appointment 类的 PatientDoctor 对象的比较是基于值,而不是基于引用。默认情况下,C# 的 == 运算符比较的是对象的引用,而不是它们的内容。因此你可以重写 EqualsGetHashCode 方法,以便通过值来进行比较。

例如,在 DoctorPatient 类中,重写这些方法:

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 或唯一标识符查找

一种常见的做法是为 PatientDoctor 以及 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);