I'm using WPF with Entity Framework and SQL, but i have a problem. Start, i'm created new data with status = false on desktop app. Next, i'm updated data on another device ( change status "false" => "true" ), and now i'm comeback to desktop app and query data with condition status = "true", load the data and binding on listview success, but on the column status data, it showing "false",it is show the right data is "true" when im restart the app. So, how can i show the newest data on Views immediately
I don't know how can it load the data with condition "true" but showing data is "false"
private void LoadData()
{
ListInventory = new ObservableCollection<Models.Inventory>(DataProvider.Ins.DB.Inventory
.Where(x => x.StatusInventory == true)
.Include(x => x.InventoryDetail));
}
Sorry for my bad english.
UPDATE:
I'm reload Dbcontext and it worked properly but i don't think it's the solution
var entity = DataProvider.Ins.DB.ChangeTracker.Entries().ToArray();
foreach (var item in entity)
{
item.Reload();
}
Related
I have a WPF application developed with Prism. I am facing a typical scenario for a code change I implemented for performance improvement.
I have a UI Grid which shows a list of entities. I select some 10 entities in the Grid and try to open it, which inturn should open a new window and load the corresponding 10 entities by resolving corresponding containers and their dependencies.
The sample code is below,,, I have commented the operations that are occuring..
private void OpenSelectedEntities(List<Entity> entities)
{
foreach (Entity entity in entities)
{
if (Application.Current != null)
{
//I implemented opening entity in async so that 10 entities will be opened without stalling the UI.
Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
OpenEntity(entity, false);
}));
}
}
}
public void OpenEntity(Entity entity, boolean val)
{
//Creating Container to load the controls.
//Adding Container to Region
//Loading the other UI related and triggering operation threads
}
The problem I am facing is, When I select some entities and verify it in my local development environment, I am able to see all the 10 entities opened and working well. However, When I deploy the code in Server and test it there,, Only two entities were opened, the first entity and last entity in the selected entities.. I am completely clueless what is causing this problem. I have cross checked twice, I am getting this problem while calling OpenEntity as Asynchronous.
Has anyone encountered situation like this using WPF and Prism.
It is an "Access to Modified Closure" problem. Look into that for more details.
Here's a blog post that discusses it. http://www.jarloo.com/access-to-modified-closure/
As for the fix, create a temp variable.
private void OpenSelectedEntities(List<Entity> entities)
{
foreach (Entity entity in entities)
{
if (Application.Current != null)
{
Entity tempEntity = entity;
Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
OpenEntity(tempEntity , false);
}));
}
}
}
This question already has an answer here:
Displaying a busy indicator when Entity Framework is loading data
(1 answer)
Closed 9 years ago.
When loading data from database with Entity Framework takes a long time I would like to show "loading" indicator on UI (WPF). For the indicator itself, I am using WPF Loading Wait Adorner as shown in the article.
The indicator works fine but is not showing when Entity Framework loads data. In that case the indicator won't show at all on UI.
I run this:
'show Adorner (loading indicator)
LoadingAdorner.IsAdornerVisible = Not LoadingAdorner.IsAdornerVisible
'read data from database with Entity Framework
Persons = _context.persons
'hide Adorner (loading indicator) after loading data is completed
LoadingAdorner.IsAdornerVisible = Not LoadingAdorner.IsAdornerVisible
and
<ac:AdornedControl Name="LoadingAdorner">
<ac:AdornedControl.AdornerContent>
<local:LoadingWait></local:LoadingWait>
</ac:AdornedControl.AdornerContent>
<ListBox>
...code not shown
</ListBox>
</ac:AdornedControl>
Only after the data is loaded, the indicator becomes visible.
What am I missing and how to show the indicator WHILE the data is loaded?
Problem is that you're running your EF call in Main thread. This blocks UI from being updated until you'll receive all data from the DB.
To fix this just add BackgroundWorker or async methods:
var worker = new BackgroundWorker();
worker.DoWork += (s, e) => {
this.IsLoading = true;
this.Persons = _context.persons;
};
worker.RunWorkerCompleted += (s, e) => {
this.IsLoading = false;
};
Important: Keep in mind cross-thread access (DoWork performed in background thread, Completed - UI thread )
And at the end to start/trigger DoWork you will need to execute .RunWorkerAsync() on your worker.
I'm using a WCF data Service to access a MSSQL database. If the client requests data (e.g. from the table "Projects") i build my cache like this:
var collection = new ObservableCollection<Project>();
foreach (var project in this.Entities.Project)
{
collection.Add(project);
}
return collection;
If I want to refresh the list I just call
collection.Clear();
and call the above method again. If I edit a project and refresh the list as described above it works fine, but if i change the data on one client instance and refresh the list on another one the service doesn't load the changed project.
How can I force the DataService to re- load a whole entity (e.g. "Projects") even if from the service's point of view nothing has changed?
Possible solution:
public partial class Entities
{
public void RefreshProject(Project pr)
{
this.Detach(pr);
pr = this.Project.Where(p => p.Id == pr.Id).Single();
}
}
Usage:
entities.RefreshProject(project);
I use Entity Framework 4 and Self Tracking Entities. The schema is like:
Patient -> Examinations -> LeftPictures
-> RightPictures
So there is TrackableCollection of these two relationships Patient 1 - * ....Pictures.
Now when loading the customers Form and browsing the details I dont need to load these
data images, only when another form is loaded for Examination details!
I am using a class library as a Data Repository to get data from the database (SQL Server) and this code:
public List<Patient> GetAllPatients()
{
try
{
using (OptoEntities db = new OptoEntities())
{
List<Patient> list = db.Patients
.Include("Addresses")
.Include("PhoneNumbers")
.Include("Examinations").ToList();
list.ForEach(p =>
{
p.ChangeTracker.ChangeTrackingEnabled = true;
if (!p.Addresses.IsNull() &&
p.Addresses.Count > 0)
p.Addresses.ForEach(a => a.ChangeTracker.ChangeTrackingEnabled = true);
if (!p.PhoneNumbers.IsNull() &&
p.PhoneNumbers.Count > 0)
p.PhoneNumbers.ForEach(a => a.ChangeTracker.ChangeTrackingEnabled = true);
if (!p.Examinations.IsNull() &&
p.Examinations.Count > 0)
p.Examinations.ForEach(e =>
{
e.ChangeTracker.ChangeTrackingEnabled = true;
});
});
return list;
}
}
catch (Exception ex)
{
return new List<Patient>();
}
}
Now I need when calling the Examination details form to go and get all the Images for the Examination relationship (LeftEyePictures, RightEyePictures). I guess that is called Lazy Loading and I dont understood how to make it happen while I'm closing the Entities connection immidiately and I would like to stay like this.
I use BindingSource components through the application.
What is the best method to get the desired results?
Thank you.
Self tracking entities don't support lazy loading. Moreover lazy loading works only when entities are attached to live context. You don't need to close / dispose context immediately. In case of WinForms application context usually lives for longer time (you can follow one context per form or one context per presenter approach).
WinForms application is scenario for normal attached entities where all these features like lazy loading or change tracking work out of the box. STEs are supposed to be used in distributed systems where you need to serialize entity and pass it to another application (via web service call).
I have a strange issue. I wonder whether it's a standard behavior of the .NET components, and how to handle this.
Our app is using galasoft mvvm light. I have a form with a tree view, which is getting the data via an asynchronous call. And why that asynchronous task is running, we're showing a progress bar to the user. I'm using ObservableCollection as a collection for my tree structure. Now the problem:
This piece of code gives us the info:
public Task<ObservableCollection<FillingTreeNode>> GetTreeStructureAsync(SyncSettings settings)
{
SearchRequest request = BuildRequest();
return searchService.SearchRecordsAsync(request).ContinueWithConversion(
records => new ObservableCollection<FillingTreeNode>(records
.Select(cabinet => new FillingTreeNode
{
IsChecked = false,
DisplayName = cabinet.Fields[Fields.CabinetName].Value,
Node = cabinet.AsFillingNode(FillingNodeType.Cabinet),
NumberOfNodes = SendXmlRequest(record),
Children = new ObservableCollection<FillingTreeNode>(GetChildren (record));
}
}
This is the task extension to convert the result to some new type:
public static Task<TNew> ContinueWithConversion<TOld, TNew>(this Task<TOld> task, Func<TOld, TNew> conversionAction)
{
return task.ContinueWith(completedTask => conversionAction(task.Result));
}
Now the issue. The data is loaded from the server, the UI (the progress bar) says that the data is loaded, and only after that SendXmlRequest(record) (which is a bit long to wait) begins to work! But i expect that it's already done. The user sees nothing until those functions are finished working
Do you know what is the cause of the problem? Can that be the behavior of the Observable collection? How can i fix it?
Thank in advance.