[英]EntityFramework 7 Error when updating record
每次我想更新我的記錄時,我都會收到以下錯誤:
“無法跟蹤實體類型 'User' 的實例,因為已在跟蹤具有相同鍵的此類型的另一個實例。添加新實體時,對於大多數鍵類型,如果未設置鍵,將創建唯一的臨時鍵值(即如果鍵屬性為其類型分配了默認值。如果您為新實體明確設置鍵值,請確保它們不會與現有實體或為其他新實體生成的臨時值沖突。附加現有實體時,請確保只有一個具有給定鍵值的實體實例附加到上下文。”
這是我的代碼:
public void SaveRecipient(Recipient myRecipient)
{
if (myRecipient.RecipientGUID == Guid.Empty)
{
myRecipient.RecipientGUID = Guid.NewGuid();
foreach (ContactMethod tmpCM in myRecipient.ContactMethods)
{
context.Entry(tmpCM.Type).State = EntityState.Unchanged;
}
context.Entry(myRecipient.LastModifiedBy).State = EntityState.Unchanged;
context.Entry(myRecipient.Owner).State = EntityState.Unchanged;
context.Entry(myRecipient.CreatedBy).State = EntityState.Unchanged;
context.Recipients.Add(myRecipient);
}
else
{
var dbRecipient = context.Recipients
.Include(a => a.ContactMethods).ThenInclude(t => t.Type)
.Include(b => b.CreatedBy)
.Include(c => c.LastModifiedBy)
.Include(d => d.Owner).ThenInclude(o => o.Users)
.FirstOrDefault(x => x.RecipientGUID == myRecipient.RecipientGUID);
if (dbRecipient != null)
{
dbRecipient.FirstName = myRecipient.FirstName;
dbRecipient.LastName = myRecipient.LastName;
dbRecipient.Company = myRecipient.Company;
foreach (ContactMethod tmpCM in myRecipient.ContactMethods)
{
var dbCM = dbRecipient.ContactMethods.FirstOrDefault(x => x.ContactMethodGUID == tmpCM.ContactMethodGUID);
if (dbCM != null)
{
dbCM.CountryCode = tmpCM.CountryCode;
dbCM.Identifier = tmpCM.Identifier;
dbCM.IsPreferred = tmpCM.IsPreferred;
}
else
{
dbRecipient.ContactMethods.Add(tmpCM);
}
}
//Only update this if it has changed.
if (dbRecipient.LastModifiedBy.UserGUID != myRecipient.LastModifiedBy.UserGUID)
{
dbRecipient.LastModifiedBy = myRecipient.LastModifiedBy;
}
dbRecipient.LastModifiedOn = myRecipient.LastModifiedOn;
}
}
context.SaveChanges();
}
相關類:
用戶:
public class User
{
[Key]
public Guid UserGUID { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public bool IsSiteAdmin { get; set; }
public bool IsActive { get; set; }
public DateTime? CreatedOn { get; set; }
public DateTime? LastLogin { get; set; }
}
接受者:
public class Recipient
{
[Key]
public Guid RecipientGUID { get; set; }
[Required(ErrorMessage = "Please enter a Recipient's First Name.")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter a Recipient's Last Name.")]
public string LastName { get; set; }
public string Company { get; set; }
public UserGroup Owner { get; set; }
public virtual ICollection<ContactMethod> ContactMethods { get; set; }
public User CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
public User LastModifiedBy { get; set; }
public DateTime LastModifiedOn { get; set; }
public bool IsActive { get; set; }
}
聯系方式:
public class ContactMethod
{
[Key]
[HiddenInput(DisplayValue = false)]
public Guid ContactMethodGUID { get; set; }
[ForeignKey("ContactMethodTypeGUID")]
public virtual ContactMethodType Type { get; set; }
public string CountryCode { get; set; }
[Required]
public string Identifier { get; set; }
public bool IsPreferred { get; set; }
[ForeignKey("RecipientGUID")]
public virtual Recipient Owner { get; set; }
}
當我想更新收件人時會發生此問題,並且是另一個用戶進行更新。 所以說用戶 abcd 做了最后一次更新,但現在用戶 zyx 更新了記錄。 因此 Recipeint.LastUpdatedBy 設置為當前會話用戶。 當我這樣做時,我收到上述錯誤。 我不知道如何超越這一點。
一個小提示:如果我添加這個:
context.Entry(myRecipient.LastModifiedBy).State = EntityState.Unchanged;
在if (dbRecipient.LastModifiedBy.UserGUID != myRecipient.LastModifiedBy.UserGUID)
語句,並說用戶 lastmodifiedby 設置為用戶 abc。 現在用戶 asfg 第一次更新這個接收者,它通過,並且 LastModifiedBy 將被設置為用戶 asfg,但是說用戶 abc 返回並再次更改接收者,所以 lastmodifiedby 返回到 abc,它失敗,出現同樣的錯誤.
這讓我發瘋,我無法弄清楚!!!
我從Microsoft 的Arthur Vickers那里得到了答案。 我想分享。
設置導航屬性dbRecipient.LastModifiedBy
的代碼將其設置為上下文未跟蹤的實體實例。 在這種情況下,上下文似乎已經在跟蹤同一實體的另一個實例——大概是因為它是通過包含CreatedBy
導航由查詢CreatedBy
。
EF 無法跟蹤同一實體的兩個實例,這就是拋出異常的原因,因此您需要在此處向 EF 提供附加信息以了解該怎么做。 在一般情況下,這可能很復雜。
例如:如果被跟蹤實例的屬性在另一個實例中已被修改。
但是,假設情況並非如此,那么您只需查找正在跟蹤的實例並使用它,例如:
if (dbRecipient.LastModifiedBy.UserGUID != myRecipient.LastModifiedBy.UserGUID)
{
dbRecipient.LastModifiedBy = test.Set<User>().Find(myRecipient.LastModifiedBy.UserGUID);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.