I do not understand how EF5 dbContext.Entry(entity).Reload() method is supposed to work?

14,533

If dbEntities is a DbContext, then you are talking about doing, effectively dbc.Entry<ART_GRUPE>().Reload();, to discard all changes and reload the entities, not reloading your query. However, this does not exist. You can discard any changes made to a single entity using the dbc.Entry<ART_GRUPE>(myEntity).Reload() ("MSDN - DbEntityEntry<TEntity>.Reload Method").

DbContext is not meant to be long lived, you are meant to use it for your query, then get rid of it. If you want to cast it to an object context, you could try:

var ctx = ((IObjectContextAdapter)db).ObjectContext;
ctx.Refresh();

This may not be what you need. It also doesn't remove entities deleted from the db from your context, and it doesn't always refresh relationships. You may be better off getting rid of the context and loading it again:

private void GetData()
{
    // you could wrap this in a using statement, though that isn't necessary
    using (var dbc = new dbEntities())
    {
        art = from a in dbc.ARTIKLIs
            select a;

        grp = from g in dbc.ART_GRUPE
            select g;

        artikliBindingSource.DataSource = art.ToList();
        artGrupeBindingSource.DataSource = grp.ToList();
    }
}
private void refresh_Click(object sender, EventArgs e)
{
    GetData();
    // not sure you need this next line now, but you should test
    artGrupeBindingSource.ResetBindings(false); 
}

The problem this may cause you is that you are making changes to ARTIKLIs and trying to track them. For that you could use something like the following to save changes, and do not reload your ARTIKLIs each time:

private void GetData(bool loadArtikli = true)
{
    // you could wrap this in a using statement, though that isn't necessary
    using (var dbc = new dbEntities())
    {
        if (loadArtikli)
        {
            art = from a in dbc.ARTIKLIs
                select a;
        }

        grp = from g in dbc.ART_GRUPE
            select g;

        artikliBindingSource.DataSource = art.ToList();
        artGrupeBindingSource.DataSource = grp.ToList();
    }
}
private void refresh_Click(object sender, EventArgs e)
{
    GetData(false);
}

public static void UpdateARTIKLI(ARTIKLI item)
{
  using (var dbc = new dbEntities())
  {
    if (item.Id > 0)
    { // update existing ones
      var dbitem = context.ARTIKLI 
        .Find(item.Id);

      context.Entry(dbItem)
        .CurrentValues
        .SetValues(item);
    }
    else
    { // deal with new ones
      context.ARTIKLI.Add(item);
    }

    context.SaveChanges();
  }
}
Share:
14,533
EmirZ
Author by

EmirZ

Updated on June 14, 2022

Comments

  • EmirZ
    EmirZ almost 2 years

    In this example :

    using System;
    using System.Collections.Generic;
    using dbModel;
    using System.Linq;
    using System.Data.Entity.Infrastructure;
    
    
    namespace WinApp
    {
        public partial class Form1 : Form
        {
            private dbEntities dbc;
            public IQueryable<ARTIKLI> art;
            public IQueryable<ART_GRUPE> grp;
    
            public Form1()
            {
                InitializeComponent();
                dbc = new dbEntities();            
            }
    
    
            private void GetData()
            {
                art = from a in dbc.ARTIKLIs
                            select a;
    
                grp = from g in dbc.ART_GRUPE
                            select g;
    
                artikliBindingSource.DataSource = art.ToList();
                artGrupeBindingSource.DataSource = grp.ToList();
            }
    
    
            private void Form1_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
            {
                dbc.SaveChanges();
            }
    
    
            private void loadData_Click(object sender, EventArgs e)
            {
                this.GetData();  
            }
    
    
            private void refresh_Click(object sender, EventArgs e)
            {
    
                dbc.Entry(grp).Reload();
                artGrupeBindingSource.ResetBindings(false);
            }
    
        }
    }
    

    everything builds OK. But when I run and click Refresh button I get error :

    The entity type DbQuery`1 is not part of the model for the current context

    I am just trying to refresh data from store for grp entity instance using DbContext. I know I can convert DbContext into ObjectContext and then use Refresh method, but it should be possible to do the same with DbContext.Entry(entity).Reload();

    Can someone explain my mistakes in the code above?

  • Wiktor Zychla
    Wiktor Zychla almost 11 years
    What instance is supposed to be?
  • Andy Brown
    Andy Brown almost 11 years
    @WiktorZychla. Corrected, thank you. instance was a figment of my lack of coffee and sleep.
  • Wiktor Zychla
    Wiktor Zychla almost 11 years
    Still wrong perhaps. Entry method requires instance parameter.
  • Andy Brown
    Andy Brown almost 11 years
    @WiktorZychla. Coffee acquired. Answer rewritten!
  • EmirZ
    EmirZ almost 11 years
    This works, and I am doing exactly this in my project... but the need to cast DbContext to ObjectContext is very much annoying. I thought that it is I who does not understand the DbContext well, but is seems that DbContext really isn't equipped with this simple functionality !?!?
  • Andy Brown
    Andy Brown almost 11 years
    @Virtuo. I think it just isn't meant to be kept hanging around or you chew up the connection pool to the database.
  • EmirZ
    EmirZ almost 11 years
    Thank you Andy! It seems I will have to reStudy EF5 and DbContext.
  • Andy Brown
    Andy Brown almost 11 years
    @Virtuo. Have a look at this as well: Entity Framework 4.1 DbSet Reload. Have also added a comment in my answer about casting to ObjectContext