2015-01-06 5 views
1

У меня есть следующая функция, которая создает новую строку или обновляет существующую строку в модели MACReg в зависимости от того, существует ли данный MAC-адрес.Запрос C# LINQ создает непреднамеренную новую строку

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 и школы ниже:

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; } 
} 

UPDATE: 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; 
} 
+0

Если вы отлаживаете, каково значение r? –

+0

Где находится "школа"? Похоже, что это может произойти из-за пределов контекста 'db'. Также это (пока) не связано с LINQ. – Rawling

+1

@ L-Three r - это объект, представляющий строку из db, когда существует макрос – totoro

ответ

4

Вашего school от другого CloudPrintDbContext, так что это не гусеничного экземпляром db в using заявления , Если он не прикреплен к какому-либо другому DbContext, вы можете прикрепить его к этому, прежде чем устанавливать School, а затем он должен работать.

db.Schools.Attach(school); 

Как и в сторону, я бы рекомендовал использовать DbSet.Create() метод вместо new, так что вы можете использовать динамические прокси, согласно EF documentation.

+0

спасибо! вы имеете в виду, что экземпляр 'school' не распознается в' RegisterMAC', поэтому он создан снова? также, вы хотите поставить 'db.Schools.Attach (school)' в RegisterMAC до 'MACReg r = db.MACRegs.Find (mac)'? но где прикреплять 'mac'? Сначала я должен «найти» экземпляр «MACReg», верно? – totoro

+0

@dragon_cat Извините, я просто видел, что MAC - это строка. Мысль это была другая сущность. – kjbartel

+0

@dragon_cat EF не знает, что «школа» - это существующая сущность, поэтому она думает, что она новая. Когда вы вызываете 'db.MACRegs.Add (m)', он также добавит 'school'. – kjbartel

Смежные вопросы