可以在代码中一直重用实体框架上下文吗?

时间:2012-01-31 20:50:19

标签: c# sql-server winforms entity-framework

this问题中,我遇到了保存具有外键的对象的问题,因为Objects是通过外键从多个Objects构建的,但它们是使用不同的上下文加载的每一次。例如:

  using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) {
        IQueryable<Konsultanci> listaKonsultantow = from k in context.Konsultancis
                                select k;

  }

然后在代码中的其他地方会有更多context用于获取更多对象类型,例如Persons,Training,您可以命名它。

然后会有代码保存它(简化):

        using (var context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM)) {
            if (context.Szkolenies.Any(t => t.SzkolenieID == currentSzkolenie.SzkolenieID)) {
                context.Szkolenies.Attach(currentSzkolenie);
                context.ObjectStateManager.ChangeObjectState(currentSzkolenie, EntityState.Modified);
            } else {
                context.Szkolenies.AddObject(currentSzkolenie);
            }
            context.SaveChanges();


       }

通常在尝试保存后会出现多条错误消息

An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key.

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects

和其他几个人。

所以为了解决这个问题,我已经在我的班级上声明了private EntityBazaCRM context = new EntityBazaCRM(Settings.sqlDataConnectionDetailsCRM);,并且一直重复使用它而不将其放入using。由于这个动作,我没有在保存或任何东西之前附加任何东西。我只是使用相同的上下文并使用currentUczestnik.Szkolenie = szkolenie;和currentUczestnik.Konsultanci = consultants;附加了我想要的任何外键。它保存没有问题。

问题:

它适用于我现在拥有的不太复杂的小型GUI。但是,如果我引入多线程,尝试使用相同的Context从不同的对象(将对象加载到GUI,到ListView等)的所有地方获取多个值?难道不会对我造成严重伤害吗?

在我发现我正在使用的实体框架之前的旧代码中:

        const string preparedCommand = @"SELECT ID FROM TABLE WHERE NAME = "TEST"";
        using (SqlConnection varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
        using (var sqlQuery = new SqlCommand(preparedCommand, varConnection))
        using (SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader())
            while (sqlQueryResult.Read()) {
                string id= sqlQueryResult["id"].ToString();
            }
        }

基本上我每次都想使用SQL连接。如果没有连接,它将被建立,如果有连接,它将被重用并且没有多线程的问题。

有人能告诉我,我发现工作的方式可以带来什么问题吗?或者也许这是最好的方式吗?

1 个答案:

答案 0 :(得分:2)

  

但是,如果我引入多线程,尝试获取多个值   来自不同对象的所有地方(将对象加载到GUI,到   ListView等)使用相同的Context?它不会对我造成伤害   我严厉的?

是的,是的。上下文基本上是数据库连接之上的薄层 - 这不是线程安全的,因此不能在线程之间重用相同的上下文。您正在寻找的是您使用相同上下文的工作单元,但是一旦完成该工作单元,您就可以处理上下文。由于您使用自己的存储库实现,因此必须在这些存储库之上构建工作单元。