Click here to Skip to main content
15,886,026 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have this code in my "Department Form"
private readonly SIMContext _SIMContext;
private Department model;
public Frm_Department(SIMContext SIMContext)
{
    InitializeComponent();
    _SIMContext = SIMContext;
}

And this is the method that get data from database I added to load event
I have BindingSource component "dataBindingSource" that assign to gridControl DataSource
private async Task LoadDataAsync()
{
        // Call the LoadAsync method to asynchronously get the data for the given DbSet from the database.
        await _SIMContext.Departments.LoadAsync().ContinueWith(loadTask =>
        {
            // Bind data to control when loading complete
            dataBindingSource.DataSource = _SIMContext.Departments.Local.ToBindingList();
        }, TaskScheduler.FromCurrentSynchronizationContext());

}

all my CRUD operations work fine (using DbContext).
Now to the problem:
If I add records directly(Manually) to the database (not using DbContext) and if I call LoadDataAsync method I get all records without any problem.
But when I edit or remove any record(Manually) (not using DbContext) and then call LoadDataAsync method I get old values not updated one.
How can I resolve this problem?.
I am using EF Core 3.1.15 with .Net 4.7.2

Update:
This is my DbContext class
public partial class SIMContext : DbContext
    {
        public SIMContext()
        {
        }
        public SIMContext(DbContextOptions<SIMContext> options)
            : base(options)
        {
        }
        public virtual DbSet<Department> Departments { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["SIMContext"].ConnectionString);
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.ApplyConfiguration(new DepartmentConfiguration());
        }

       
    }

and this is how I inject DbContext using AutoFac
static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        public static IContainer Container;
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Container = Configure();
            Application.Run(new XtraMain(Container.Resolve<SIMContext>()));
        }
        static IContainer Configure()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<SIMContext>().AsSelf();
            builder.RegisterType<XtraMain>();
            return builder.Build();
        }
    }

And This is the main form:
public partial class XtraMain : DevExpress.XtraBars.Ribbon.RibbonForm
    {
        private readonly SIMContext _SIMContext;
        public XtraMain(SIMContext SIMContext) 
        {
            InitializeComponent();
            _SIMContext = SIMContext;
        }
        private void bbtnDepartment_ItemClick(object sender, ItemClickEventArgs e)
        {
            Frm_Department frme = new(_SIMContext)
            {
                Name = "Frm_Department"

            };
            ViewChildForm(frme);
        }
    }


What I have tried:

dataBindingSource.ResetBindings(false);

var state = _SIMContext.Entry(model).State;
state = EntityState.Modified;
Posted
Updated 5-Aug-21 4:52am
v2
Comments
Richard Deeming 5-Aug-21 6:16am    
That LoadDataAsync method looks odd. Why would you use .ContinueWith in an async method? Just use:
private async Task LoadDataAsync()
{
    await _SIMContext.Departments.LoadAsync();
    dataBindingSource.DataSource = _SIMContext.Departments.Local.ToBindingList();
}

1 solution

Once Entity Framework has loaded and tracked an entity, it will use the properties of that entity, even if the database values are different. You have to explicitly tell it to reload the database values.

Unfortunately, there's no way in EF Core to bulk-reload all of the entities in a set. You have to reload each entity in turn. This could result in a lot of queries to the database:
C#
private async Task LoadDataAsync(bool refresh = false)
{
    if (refresh)
    {
        var departments = await _SIMContext.Departments.ToListAsync();
        foreach (var department in departments)
        {
            await _SIMContext.Entry(department).ReloadAsync();
        }
    }
    else
    {
        await _SIMContext.Departments.LoadAsync();
    }
    
    dataBindingSource.DataSource = _SIMContext.Departments.Local.ToBindingList();
}

There is an open ticket on the EF Core backlog to add a bulk-reload feature:
Ability to refresh a context from the database · Issue #16491 · dotnet/efcore · GitHub[^]
 
Share this answer
 
Comments
Mahfoud Bouabdallah 5-Aug-21 9:30am    
thank you very much for your help.
The modifying records was updated.

But removed records does not affected
Richard Deeming 5-Aug-21 9:59am    
That's odd.

The only other option would be to dispose of the context instance, and create a new one. But that would obviously only work if you're not using anything other than the list of departments.
Mahfoud Bouabdallah 5-Aug-21 10:40am    
Yes, that's right
I add this line
dataBindingSource.ResetBindings(false);
to the end of method to view modifying records.
When I removed record, I get the correct data on
var departments = await _SIMContext.Departments.ToListAsync();
Dave Kreskowiak 5-Aug-21 10:06am    
Why does it look like you're using a single instance of your dbContext class, shared throughout your data class?

Are you keeping a single instance of your dbContext alive throughout the lifetime of your application, or similar?
Mahfoud Bouabdallah 5-Aug-21 10:54am    
I have Updated my question, please see it

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900