【问题标题】:Can Entity Framework context be reused all the time in code?实体框架上下文可以在代码中一直重用吗?
【发布时间】:2012-01-31 20:50:19
【问题描述】:

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 = advisors; 附加了我想要的任何外键。它保存没有问题。

问题:

它适用于我现在拥有的并不过分复杂的小型 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 时都会使用它。如果没有连接,它将被建立,如果有连接,它将被重用,并且多线程没有问题。

谁能告诉我按照我发现的工作方式做这件事会遇到什么问题?或者也许这是最好的方法?

【问题讨论】:

  • This 可以解释为什么不应该将上下文用于单个业务单元工作(单线程逻辑业务操作)以外的任何事情。

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


【解决方案1】:

但是如果我引入多线程,尝试获取多个值怎么办 来自不同地方的不同对象(将对象加载到 GUI, ListView 等)使用相同的上下文?它不会对我造成伤害吗 我严重吗?

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    相关资源
    最近更新 更多