[英]WPF Entity Framework refresh one context entity
I have a simple MVVM WPF app with database-first EF dbContext (which is Global.Database
in my app), which is long-living in my application. 我有一个简单的MVVM WPF应用程序,其数据库优先EF dbContext(在我的应用程序中为Global.Database
在我的应用程序中长期存在。 I have a window with a listbox with ItemsSource
binded to viewmodel property called Clients
which is an ObservableCollection
of my dbmodel Client
. 我有一个带有列表框的窗口,其中的ItemsSource
绑定到名为Clients
viewmodel属性,这是我的dbmodel Client
的ObservableCollection
。
The SelectedItem
of this listbox is binded to a viewmodel property called SelectedClient
. 此列表框的SelectedItem
绑定到名为SelectedClient
的视图模型属性。
In Client
entity class there is a field called last_status
which is a simple int from my database. 在Client
实体类中,有一个名为last_status
的字段,这是我数据库中的一个简单整数。
So, in my view, when i select client from listbox, a label binded to SelectedClient's last_status
should show the value of last_status
. 所以,在我看来,当我从列表框中选择客户端,一个标签绑定到SelectedClient的last_status
应该显示的值last_status
。
I added a button and a refresh command into my viewmodel. 我在视图模型中添加了一个按钮和一个刷新命令。 All i want is: when i manually change last_status
for the client in my database and press refresh button in my view, the content of label should change. 我想要的是:当我在数据库中手动更改客户端的last_status
并在视图中按“刷新”按钮时,标签的内容应更改。 But i have absolutely no idea how to achieve this. 但是我绝对不知道如何实现这一目标。 Here is the part of my viewmodel code (i use Catel, but it doesn't matter for this case): 这是我的视图模型代码的一部分(我使用Catel,但在这种情况下并不重要):
public ClientManagerWindowViewModel()
{
RefreshClientInfoCommand = new Command(OnRefreshClientInfoCommandExecute);
Clients = new ObservableCollection<Client>();
RefreshClients();
}
public ObservableCollection<Client> Clients
{
get { return GetValue<ObservableCollection<Client>>(ClientsProperty); }
set { SetValue(ClientsProperty, value); }
}
public static readonly PropertyData ClientsProperty = RegisterProperty("Clients", typeof(ObservableCollection<Client>));
public Client SelectedClient
{
get
{return GetValue<Client>(SelectedClientProperty);}
set
{
SetValue(SelectedClientProperty, value);
}
}
public static readonly PropertyData SelectedClientProperty = RegisterProperty("SelectedClient", typeof(Client));
//here is my refresh button command handler:
public Command RefreshClientInfoCommand { get; private set; }
private void OnRefreshClientInfoCommandExecute()
{
RefreshClientInfo(SelectedClient);
}
//and here is my "logic" for working with dbcontext:
private void RefreshClients()
{
var qry = (from c in Global.Database.Clients where c.client_id != 1 select c).ToList();
Clients = new ObservableCollection<Client>(qry);
}
private void RefreshClientInfo(Client client)
{
Global.Database.Entry(client).Reload();
}
My XAML for a listbox: 我的XAML用于列表框:
<ListBox
x:Name="ClientsListBox"
Grid.Row="1"
Margin="5"
DisplayMemberPath="fullDomainName"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Clients}"
SelectedItem="{Binding SelectedClient}" />
My XAML for a label: 我的XAML标签:
<Label Margin="5" Content="{Binding SelectedClient.last_status}" />
And for a button: 对于按钮:
<Button Command="{Binding RefreshClientInfoCommand}" Content="↻"/>
For now, when i change a client's last_status
value manually in database and press refresh button nothing happens. 现在,当我在数据库中手动更改客户端的last_status
值并按“刷新”按钮时,没有任何反应。 But when i select another client in a listbox and then return to needed client - label content updates correctly. 但是,当我在列表框中选择另一个客户端,然后返回所需的客户端时-标签内容正确更新。 I know, maybe i miss something very stupid and simple, but i cant' figure out what exactly. 我知道,也许我想念一些非常愚蠢和简单的东西,但是我无法弄清楚到底是什么。 Maybe i need to force change SelectedClient
in my button command handler, or call SelectedClient
s setter somehow... Please, help me. 也许我需要在按钮命令处理程序中强制更改SelectedClient
或以某种方式调用SelectedClient
的设置器...请帮助我。 Thanks a lot. 非常感谢。
Well, i figured out what was wrong with my code. 好吧,我弄清楚了我的代码出了什么问题。
My databindig was set to SelectedClient.last_status
. 我的databindig设置为SelectedClient.last_status
。 For some reason it didn't work as i expected. 由于某种原因,它没有按我的预期工作。 So i created a new viewmodel property called LastStatus and modified my RefreshClientInfo: 因此,我创建了一个名为LastStatus的新viewmodel属性,并修改了RefreshClientInfo:
private void RefreshClientInfo(Client client)
{
Global.Database.Entry(client).Reload();
LastStatus = client.last_status;
SetValue(SelectedClientProperty, client);
}
and binded label to this new property. 并将标签绑定到此新属性。 Now everything works correct. 现在一切正常。
You need to set the SelectedClient
property to the new Client
object that you get back from the EF query. 您需要将SelectedClient
属性设置为从EF查询返回的新Client
对象。
You could do this by storing the client_id
of the currently selected client before you query the database and then select the new Client
object with this particular client_id
. 您可以通过在查询数据库之前存储当前选定客户端的client_id
来执行此操作,然后使用该特定的client_id
选择新的Client
对象。
Try this: 尝试这个:
private void RefreshClients()
{
int? currentlySelectedClientId = (SelectedClient != null) ? SelectedClient.client_id : default(int?);
var qry = (from c in Global.Database.Clients where c.client_id != 1 select c).ToList();
Clients = new ObservableCollection<Client>(qry);
if (currentlySelectedClientId.HasValue)
SelectedClient = Clients.FirstOrDefault(x => x.client_id = currentlySelectedClientId.Value);
}
Edit: Make sure that you fetch the updated records from the DB: 编辑:请确保您从数据库中获取更新的记录:
private void RefreshClientInfo(Client client)
{
var newClient = (from c in Global.Database.Clients where c.client_id == client.client_id select c).ToList();
SetValue(SelectedClientProperty, newClient[0]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.