[英]Entity Framework 5 Update works only once per object / row
我正在將Entity Framework 5與MySQL數據庫一起使用,只是想在0和1之間更新行屬性"user_loginstatus"
。第一次通過客戶端登錄時,第一次嘗試更新就很好,嘗試再次更新后毫無例外地什么也不做。
我這樣登錄:
public async void LoginExecute()
{
// Checking Connection before etc...
if (await _dataService.IsLoginDataValidTask(UserObj.Username, md5))
{
Trace.WriteLine("LoginCommand Execute: Eingeloggt");
UserObj = await _dataService.GetUserDataTask(UserObj.Username);
await _dataService.SetUserStatusTask(UserObj.Id, 1);
await _dataService.WriteLog(UserObj.Id, "login", "Programm", GetLocalAdress());
Messenger.Default.Send(UserObj);
Messenger.Default.Send(new NotificationMessage("GoToMenuPage"));
}
else
{
// Error Stuff...
}
}
DataService類中的SetUserStatus方法
public Task SetUserStatusTask(int id, int status)
{
return Task.Factory.StartNew(() =>
{
try
{
var user = _entities.users.Find(id);
user.user_loginstatus = status;
_entities.SaveChanges();
}
catch (Exception ex)
{
Trace.WriteLine("DataService SetUserStatusTask: " + ex.Message);
}
});
}
DataService類中的GetUserData方法
public Task<User> GetUserDataTask(string username)
{
return Task.Factory.StartNew(() =>
{
try
{
var user = from us in _entities.users
where us.user_name.Equals(username)
select new User
{
Id = us.user_id,
Username = us.user_name,
FirstName = us.user_firstname,
LastName = us.user_lastname,
Gender = us.user_gender,
Email = us.user_mail,
Group = us.user_usergroup,
Avatar = us.user_avatar,
LoginStatus = 1
};
return user.FirstOrDefault();
}
catch (Exception ex)
{
Trace.WriteLine("DataService GetUserDataTask: " + ex);
return null;
}
});
}
因此, "users"
是我數據庫中的表, "User" / "UserObj"
我的自定義對象。 使用Messenger
(來自MVVM Light),我只是通過MainViewModel設置了Views,重置未使用的ViewModels( ViewModel = new VieModel(...);
或ViewModel = null;
)並傳遞當前/已登錄的用戶對象。
使用相同的策略,我只是這樣注銷
public ICommand LogoutCommand
{
get
{
return new RelayCommand(async () =>
{
await _dataService.SetUserStatusTask(CurrentUser.Id, 0);
if(CurrentUser.Id > 0 && IsLoggedIn)
await _dataService.WriteLog(CurrentUser.Id, "logout", "Programm", GetLocalAdress());
IsLoggedIn = false;
CurrentUser = new User();
Messenger.Default.Send(new NotificationMessage("GoToLoginPage"));
});
}
}
因此,我可以經常使用正在運行的客戶端登錄,但是"user_loginStatus"
僅將第一次登錄時間的更改設置為1,然后又重新設置為0,但是當我注銷然后再使用同一用戶登錄時,它不會改變它了。 當我與另一個用戶登錄(仍在運行客戶端時)時,它第一次將"user_loginstatus"
為1,然后又設置為0,然后在重新啟動客戶端時再次設置。
我該怎么辦?
在LoginExecute()中,您具有UserObj,但在LogoutCommand()中,您具有CurrentUser。 可以嗎
這基本上是我對原始問題的評論:
我有幾次類似的問題。 通常,它基於以下事實:您修改的實體無法正確驗證,並且dbContext在沒有適當異常的情況下失敗,因為它仍然保留為假實體。 如果是這種情況,則可以通過使用作用域上下文並將數據訪問操作嵌入using語句中來規避此問題。
或者,您可以嘗試明確告訴EF實體已更改,例如:
_entities.Entry(user).State = EntityState.Modified;
關於其他問題:
從理論上講,您不必明確地告訴EF實體的值已更改。 變更跟蹤應該自動執行。 我能想到的唯一例外是,當您嘗試修改不再明確跟蹤的實體時。 當您調用_entities.Find(id)時,它將在上下文中查找是否找到具有匹配主鍵值的對象並將其加載。 由於您之前已經修改了該對象,因此上下文將僅獲取您已經修改過的舊對象,以便首次設置登錄狀態。
可能不再跟蹤該“舊”對象,您必須通過將其狀態從“已附加”更改為“已修改”,來明確告知EF它已更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.