簡體   English   中英

為什么我的媒體資源不知道直接對數據庫所做的更改

[英]Why isn't my property aware of changes made directly to the database

我有一個簡單的View和ViewModel。 當您單擊技術員組合框並選擇技術員時,針對所選技術員的測試將顯示在下面顯示的ListView中。 這工作得很好。

注意技術人員與Test具有一對多關系,並且每個都是實體(代碼優先實體框架)。

MainViewModel.xaml

<Grid>
    <StackPanel>
        <ComboBox ItemsSource="{Binding Technicians, Mode=TwoWay}"
                  DisplayMemberPath="FullName"
                  SelectedItem="{Binding SelectedTechnician, Mode=TwoWay}">
        </ComboBox>
        <ListView ItemsSource="{Binding SelectedTechnician.Tests}"
                  SelectedItem="{Binding SelectedTest}"
                  HorizontalAlignment="Left" Height="100" Margin="10,10,0,0" VerticalAlignment="Top" Width="271">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Id" Width="auto" DisplayMemberBinding="{Binding Id}"/>
                    <GridViewColumn Header="Test" Width="auto" DisplayMemberBinding="{Binding TestTypeName}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </StackPanel>
</Grid>

MainWindowViewModel.cs

public class MainWindowViewModel : ViewModelBase
{
    private WpfTestBedDb db = new WpfTestBedDb();

    public MainWindowViewModel()
    {
        Technicians = new ObservableCollection<Technician>();
    }

    private ObservableCollection<Technician> _technicians;

    public ObservableCollection<Technician> Technicians
    {
        get { return _technicians; }
        set
        {
            _technicians = value;
            OnPropertyChanged("Technicians");
        }
    }

    private Technician _selectedTechnician;

    public Technician SelectedTechnician
    {
        get { return _selectedTechnician; }
        set
        {
            if (_selectedTechnician != value)
            {
                _selectedTechnician = value;
                OnPropertyChanged("SelectedTechnician");
            }
        }
    }

    public void LoadTechnicians()
    {
        var query = from tech in db.Technicians
                    select tech;
        foreach (var technician in query)
        {
            Technicians.Add(technician);
        }
    }
}

附帶地,要測試ObservableCollection<Technician> Technicians;上的數據綁定功能ObservableCollection<Technician> Technicians; ,如您在上面的ViewModel中所見,我通過SSMS進入數據庫並添加了一個新的Technician,而該應用仍在運行。 添加完我的內容后,我轉到該應用程序,然后單擊我的ComboBox of Technicians,發現列表/ UI尚未更新。 但是,我會以為,因為我已經將技術人員屬性設置為ObservableCollection,並提出了OnPropertyChanged("Technicians"); ,則用戶界面將已更新。

我做了這個實驗,以模擬同時運行的兩個相同應用程序,每個應用程序都讀取和寫入相同的數據庫。

第一個問題:盡管我的ObservableCollection提高了OnPropertyChanged,為什么UI沒有更新? 也就是說,為什么它不知道直接對數據庫(應用程序外部)所做的更改?

第二個問題:我需要添加什么以便技術人員不斷了解數據庫更改? (我認為這就是ObservableCollection的目的)

簡短版本:大多數數據訪問代碼是斷開連接的模型,而不是實時/連接的模型。

這里的“可觀察的”是指“對該層中的其他更改做出反應”,即操縱對象模型的其他.NET代碼。 使用ObservableCollection<T>不會使龐大的手從數據庫通過網絡伸出來調整位。

即時創建具有變更意識的系統要比這復雜得多。 坦率地說,如果您確實需要即時更新,我建議您看一下pub / sub之類的東西。 否則, 也許考慮偶爾進行輪詢。

此外,請注意,如果您確實想進行輪詢,則不能僅通過以下方式重新獲取對象:

var stateNow = db.Technicians.Single(x => x.Id == myId);

因為這樣可能會使您退回已經擁有的同一對象 ; 許多ORM都內置有身份緩存。要真正重新獲取對象,您將需要第二個db-context實例。

除了Marc Gravell的答案以及第二個問題的答案外,您可能想查看SqlDependency類。

引用文檔

SqlDependency對象表示應用程序和SQL Server實例之間的查詢通知依賴關系。 應用程序可以創建SqlDependency對象並注冊以通過OnChangeEventHandler事件處理程序接收通知。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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