C# 实体框架5更新仅对每个对象/行工作一次
我在MySQL数据库中使用Entity Framework 5,只想更新0和1之间的行属性“user\u loginstatus”。当我第一次通过客户端登录时,第一次尝试时它会更新得很好,再次尝试更新后,它不会做任何事情,没有例外 我是这样登录的: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(
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刚刚修复了它!如果你在回答中这样做,我可以将它标记为正确的。但是为什么我需要手动说它已更改?在我“提交”之前它只是处于临时状态吗用那种行动?