C# 实体框架5更新仅对每个对象/行工作一次

C# 实体框架5更新仅对每个对象/行工作一次,c#,mysql,wpf,entity-framework,mvvm,C#,Mysql,Wpf,Entity Framework,Mvvm,我在MySQL数据库中使用Entity Framework 5,只想更新0和1之间的行属性“user\u loginstatus”。当我第一次通过客户端登录时,第一次尝试时它会更新得很好,再次尝试更新后,它不会做任何事情,没有例外 我是这样登录的: public async void LoginExecute() { // Checking Connection before etc... if (await _dataService.IsLoginDataValidTask(

我在MySQL数据库中使用Entity Framework 5,只想更新0和1之间的行属性“user\u 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);
        }
    });
}
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;
        }
    });
}
DataService类中的GetUserData方法

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);
        }
    });
}
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;
        }
    });
}
因此,我可以经常使用运行中的客户端登录,但是
的“user\u loginStatus”
只会将第一次登录的时间设置为1,然后再重新设置为0,但是当我退出并使用同一用户重新登录时,它不会再更改。当我使用另一个用户登录(仍然是同一个正在运行的客户端)时,它会再次将
“user\u loginstatus”
的第一次设置为1并返回到0,然后仅在我重新启动客户端时再次设置


我会做错什么?

在LoginExecute()中有UserObj,但在LogoutCommand()中有CurrentUser。可以吗?

这基本上是我对原始问题的评论:


我有过好几次类似的问题。通常,它基于这样一个事实,即您修改的实体无法正确验证,并且您的dbContext在没有适当异常的情况下失败,因为它仍然保留假实体。如果是这种情况,您可以通过使用作用域上下文并将数据访问操作嵌入using语句来避免这个问题

或者,您可以尝试明确告诉EF实体有更改,例如:

_entities.Entry(user).State = EntityState.Modified;
关于你的另一个问题:

理论上,您不应该明确地告诉EF实体的值已更改。变更跟踪应该自动完成。我能想到的唯一例外是,当您试图修改一个不再显式跟踪的实体时。调用_entities.Find(id)时,它将在上下文中查找是否找到具有匹配主键值的对象并加载它。因为您之前已经修改过这个对象,所以上下文只会获取您已经修改过的旧对象,以便第一次设置登录状态


这个“旧”对象可能不再被跟踪,您必须通过将其状态从“已附加”更改为“已修改”来明确告诉EF它已更改。

这应该是一个答案吗?看起来更像是meYes的注释,因为在我的MainViewModel中,我有一个对象CurrentUser(来自custom Object User),它被传递给其他ViewModel,如LoginViewModel。。其中包括LoginExecute,它将UserObj作为CurrentUser传递回MainViewModel。我只是无法重写每行/每用户的user\u loginstatus属性。。这和修改状态有关吗?@Tseng,对不起,这肯定不是答案,但我的名声不允许对这个问题发表评论:(我有过几次类似的问题。通常这是基于这样一个事实,即您修改的实体无法正确验证,并且您的dbContext在没有适当异常的情况下失败。如果是这种情况,您可以通过使用作用域上下文并将数据访问操作嵌入using语句来规避此问题。或者,您可以尝试显式地告诉EF实体有更改,例如:\u entities.Entry(user.State=EntityState.Modified;@narain谢谢,将EntityState设置为Modified刚刚修复了它!如果你在回答中这样做,我可以将它标记为正确的。但是为什么我需要手动说它已更改?在我“提交”之前它只是处于临时状态吗用那种行动?