简体   繁体   English

UserControl和EF上下文处理

[英]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: 我有一个UserControl,使用我的EF上下文将数据从数据库加载到dataGridView,以使用户能够进行一些更改:

    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 (ie 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. 我想在离开UserControl时处置上下文(即导航到另一个UserControl),但是在UserControl的Dispose方法(在生成的代码中)上调用context.Dispose()似乎不起作用,因为它仅当我关闭整个WinForm时才调用。 I cannot use the " using " because I need to keep the context open to perform changes and then save. 我不能使用“ using ”,因为我需要保持上下文开放以执行更改然后保存。

The question is: how can I correctly dispose the context when I leaving the UserControl? 问题是:离开UserControl时如何正确处理上下文? THANKS! 谢谢!

I believe it is considered bad practice to keep the EF context open. 我认为保持EF环境开放是不正确的做法。 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. 而是在需要时创建上下文的新实例。确实,将上下文包装在using语句中将通过垃圾回收自动处理它。

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. 我同意最好一次性添加多个实体,您所需要做的只是一个foreach循环,也许还有一个bool属性,用于指示MyEntity实例是否已更新。 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;
}

Using EF directly in user control is bad practice. 在用户控制中直接使用EF是不好的做法。 Look here in another question 在另一个问题中看这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM