实体框架上下文是否可以在代码中一直重复使用

本文关键字:一直 代码 上下文 框架 是否 实体 | 更新日期: 2023-09-27 18:21:59

在这个问题中,我在保存具有外键的对象时遇到了问题,因为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。但是,如果我引入多线程,尝试使用相同的上下文从各处为不同的对象(将对象加载到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时都会使用它。如果没有连接,它就会被建立,如果有连接,它会被重用,并且多线程没有问题。

有人能告诉我,按照我发现的工作方式,我会遇到什么问题吗?或者也许这是最好的方法?

实体框架上下文是否可以在代码中一直重复使用

但是,如果我引入多线程,尝试获取多个值呢从各处为不同的对象(将对象加载到GUIListView等)?它不会对我造成伤害吗我很严厉?

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