簡體   English   中英

實體框架5更新每個對象/行僅工作一次

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM