C# LINQ 查询创建意外的新行

C# LINQ query creates unintended new row

我有以下功能,可以根据给定的 mac 地址是否存在在模型 MACReg 中创建新行或更新现有行。

public Boolean RegisterMAC(string pwd, string mac, string location)
{
    School school = getSchoolByCode(pwd);
    if (school == null)
    {
        return false;
    }
    //initial register or update
    using (CloudPrintDbContext db = new CloudPrintDbContext())
    {
        MACReg r = db.MACRegs.Find(mac);
        if (r == null) //create new row
        {
            MACReg m = new MACReg { MAC = mac, Location = location,
                School = school, RegTime = DateTime.Now, UpdateTime = DateTime.Now };
            db.MACRegs.Add(m);
        }
        else //update location
        {
            r.School = school;
            r.Location = location;
            r.UpdateTime = DateTime.Now;
        }
        db.SaveChanges();
    }
    return true;
}

但是,问题是它总是在模型 School(而不是 MACReg)中创建一个新行。知道为什么吗?谢谢!

MACReg 和 School 的模型如下:

public class MACReg
{
    [Key]
    public string MAC { set; get; }

    [Required]
    public School School { set; get; }

    [Required]
    public string Location { set; get; }

    [Required]
    public DateTime UpdateTime { set; get; }

    [Required]
    public DateTime RegTime { set; get; }
}

public class School
{
    [Key]
    public int SchoolID { set; get; }

    [Required]
    public string SchoolName { set; get; }

    [Required]
    public DateTime CreateTime { set; get; }

    [Required]
    public DateTime PwdExprTime { set; get; }

    [Required]
    public byte[] PwdHash { set; get; }

    [Required]
    public byte[] Salt { set; get; }
}

更新:getSchoolByCode 低于

private School getSchoolByCode(string pwd)
{
    using (CloudPrintDbContext db = new CloudPrintDbContext())
    {
        foreach(School s in db.Schools.Where(s => s.PwdExprTime > DateTime.Now)){
            byte[] userH = HashUtils.GenerateHash_Salt(pwd, s.Salt);
            if (HashUtils.CompareByteArrays(userH, s.PwdHash))
            {
                return s;
            }
        }
    }
    return null;
}

您的 school 来自不同的 CloudPrintDbContext,因此它不会被 using 语句中的 db 实例跟踪。如果它没有附加到任何其他 DbContext,那么您可以在设置 School 之前将它附加到那个 DbContext,然后它应该可以工作。

db.Schools.Attach(school);

顺便说一句,我建议您使用 DbSet.Create() 方法而不是 new,这样您就可以按照 EF documentation 使用动态代理。