2017-10-11 99 views
1

我正在編寫一個asp.net控制檯應用程序,該應用程序從.csv文件讀取值並相應地更新我們的數據庫。 在此代碼中,我將根據.csv文件中的值創建Contact的新實例。 如果聯繫人表包含相同的聯繫人(與類似的電子郵件聯繫),則更新現有聯繫人,但如果聯繫人不存在,則創建一個新聯繫人。這裏是我的代碼: -ObjectStateManager中已存在具有相同鍵的對象,ObjectStateManager無法使用相同鍵追蹤多個對象

Contact contact = new Contact() 
{ 
    RecordId = fields[RecordIdIndex], 
    Salutation = fields[SalutationIndex], 
    firstName = fields[FirstNameIndex], 
    LastName = fields[LastNameIndex], 
    Organization = fields[OrganizationIndex], 
    Title = fields[TitleIndex], 
    Phone = fields[PhoneIndex], 
    Email = fields[EmailIndex], 
    // Properties go here... 
}; 

if (!String.IsNullOrEmpty(contact.Email) && entities.Contacts.Any(a => a.Email.ToLower() == contact.Email.ToLower())) 
{ 
    // Contact already exists. Remove old. 
    var dbcontact = entities.Contacts.FirstOrDefault(a => a.Email.ToLower() == contact.Email.ToLower()); 
    int contactid = dbcontact.ID; 
    dbcontact = contact; 
    dbcontact.ID = contactid; 
    entities.Entry(dbcontact).State = EntityState.Modified; 
} 
else 
{ 
    entities.Contacts.Add(contact); 
} 

entities.SaveChanges(); 

Contact.ID是一個數據庫ID,不.csv文件中存在。 上面的代碼會引發以下異常: -

具有相同鍵的對象已經存在於 ObjectStateManager。 ObjectStateManager無法使用相同的密鑰跟蹤多個 對象。

但我不確定爲什麼會發生這種情況。我只有2個Contact對象,其中一個是ID=0,代表.csv文件中的聯繫人信息,另一個是dbcontact。它是否正確?

+0

即使固定時,這可能不是最有效的方式。你期望每個文件更新/插入多個聯繫人嗎? –

+0

@johnG這解決了嗎? – aaron

+0

@johnG這解決了嗎? – aaron

回答

1

dbcontact = contact不會更改在DbContext跟蹤參考。

這裏是處理這兩種情況沒有代碼重複一個清晰的方式:

private void Update(Contact contact, string[] fields) 
{ 
    contact.RecordId = fields[RecordIdIndex]; 
    contact.Salutation = fields[SalutationIndex]; 
    contact.firstName = fields[FirstNameIndex]; 
    contact.LastName = fields[LastNameIndex]; 
    contact.Organization = fields[OrganizationIndex]; 
    contact.Title = fields[TitleIndex]; 
    contact.Phone = fields[PhoneIndex]; 
    contact.Email = fields[EmailIndex]; 
    // Properties go here... 

    return contact; 
}; 

public void CreateOrUpdate() 
{ 
    if (!String.IsNullOrEmpty(contact.Email) && entities.Contacts.Any(a => a.Email.ToLower() == contact.Email.ToLower())) 
    { 
     // Contact already exists 
     var dbcontact = entities.Contacts.FirstOrDefault(a => a.Email.ToLower() == contact.Email.ToLower()); 
     Update(dbcontact, fields); 
     entities.Entry(dbcontact).State = EntityState.Modified; 
    } 
    else 
    { 
     var contact = new Contact(); 
     Update(contact, fields); 
     entities.Contacts.Add(contact); 
    } 

    entities.SaveChanges(); 
} 
+0

所以你的意思是我得到的錯誤是,當我做'dbcontact = contact'這將迫使兩個對象具有相同的密鑰? –

+0

不會。當您執行'dbcontact = contact'時,EF仍在跟蹤原始的'dbcontact'。當你做'Entity.Entry(dbcontact).State = EntityState.Modified;'時,EF現在也用同一個鍵跟蹤新的'contact'。 – aaron

+0

@johnG這個問題解決了嗎? – aaron

相關問題