andrew0007
andrew0007

Reputation: 1265

UserControl and EF context dispose

I have a UserControl where I am using my EF context to load the data from DB to a dataGridView in order to enable the user to make some changes:

    public partial class MyUserControl: UserControl
    {
        MyEntities context;

        public ViewMasterData()
        {
            InitializeComponent();
            createComboBoxTable();
        }

        private void MyUserControl_Load(object sender, EventArgs e)
        {
            context = new MyEntities();
        }

    // Other methods to fill the dataGridView and Save the data back to the DB

        private void SaveChanges()
        {
            context.SaveChanges();                
        }
    }

I would like to dispose the context when I am leaving the UserControl (i.e. navigate to another UserControl), but it seems that calling context.Dispose() on the Dispose method of the UserControl (in the code-generated) is not working since it is called only when I close the whole WinForm. I cannot use the "using" because I need to keep the context open to perform changes and then save.

The question is: how can I correctly dispose the context when I leaving the UserControl? THANKS!

Upvotes: 0

Views: 555

Answers (2)

Ozzy
Ozzy

Reputation: 303

Using EF directly in user control is bad practice. Look here in another question

Upvotes: 0

Fredrik
Fredrik

Reputation: 2317

I believe it is considered bad practice to keep the EF context open. Instead create a new instance of your context whenever you need it.. Indeed, wrapping the context within a using statement will dispose of it automatically via garbage collecion.

public partial class MyUserControl: UserControl
{
    // MyEntities context; i dont need this

    public ViewMasterData()
    {
        InitializeComponent();
        // createComboBoxTable();
    }

    private void MyUserControl_Load(object sender, EventArgs e)
    {
        using (var context = new MyEntitiesContext())
        {
            createComboBoxTable(context.MyEntities.ToList());
        }
    }

    private void SaveNewMyEntity(MyEntity newEntity)
    {
        using (var context = new MyEntitiesContext())
        {
            // some logic here to check for uniqueness etc

            context.MyEntities.Add(newEntity);
            context.SaveChanges(); 
        }
    }

    private void UpdateExistingMyEntity(MyEntity updatedEntity)
    {
        using (var context = new MyEntitiesContext())
        {
            context.Entry(updatedEntity).State = EntityState.Modified;
            context.SaveChanges(); 
        }
    }
}

UPDATE:

I agree its better to add multiple entities in one go, all you need is a foreach loop, and perhaps a little bool property indicating if a MyEntity instance has been updated. Something like this is a possible solution:

private void UpdateExistingMyEntity(IEnumerable<MyEntity> updatedEntities)
{
    using (var context = new MyEntitiesContext())
    {
        foreach(MyEntity e in updatedEntities)
            context.Entry(e).State = EntityState.Modified;

        context.SaveChanges(); 
    }
}

When the user clicks the Save button ...

private void saveBtn_Click(object sender, RoutedEventArgs e)
{
    IEnumerable<MyEntity> updatedEntities = myGridData.Where(o => o.HasBeenUpdated == true);

    UpdateExistingMyEntity(updatedEntities);

    foreach(MyEntity e in updatedEntities)
        e.HasBeenUpdated = false;
}

Upvotes: 1

Related Questions