小编典典

来自实体框架的 SqlException - 不允许新事务,因为会话中正在运行其他线程

all

我目前收到此错误:

System.Data.SqlClient.SqlException:不允许新事务,因为会话中还有其他线程在运行。

运行此代码时:

public class ProductManager : IProductManager
{
    #region Declare Models
    private RivWorks.Model.Negotiation.RIV_Entities _dbRiv = RivWorks.Model.Stores.RivEntities(AppSettings.RivWorkEntities_connString);
    private RivWorks.Model.NegotiationAutos.RivFeedsEntities _dbFeed = RivWorks.Model.Stores.FeedEntities(AppSettings.FeedAutosEntities_connString);
    #endregion

    public IProduct GetProductById(Guid productId)
    {
        // Do a quick sync of the feeds...
        SyncFeeds();
        ...
        // get a product...
        ...
        return product;
    }

    private void SyncFeeds()
    {
        bool found = false;
        string feedSource = "AUTO";
        switch (feedSource) // companyFeedDetail.FeedSourceTable.ToUpper())
        {
            case "AUTO":
                var clientList = from a in _dbFeed.Client.Include("Auto") select a;
                foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
                {
                    var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
                    foreach (RivWorks.Model.Negotiation.AutoNegotiationDetails companyFeedDetail in companyFeedDetailList)
                    {
                        if (companyFeedDetail.FeedSourceTable.ToUpper() == "AUTO")
                        {
                            var company = (from a in _dbRiv.Company.Include("Product") where a.CompanyId == companyFeedDetail.CompanyId select a).First();
                            foreach (RivWorks.Model.NegotiationAutos.Auto sourceProduct in client.Auto)
                            {
                                foreach (RivWorks.Model.Negotiation.Product targetProduct in company.Product)
                                {
                                    if (targetProduct.alternateProductID == sourceProduct.AutoID)
                                    {
                                        found = true;
                                        break;
                                    }
                                }
                                if (!found)
                                {
                                    var newProduct = new RivWorks.Model.Negotiation.Product();
                                    newProduct.alternateProductID = sourceProduct.AutoID;
                                    newProduct.isFromFeed = true;
                                    newProduct.isDeleted = false;
                                    newProduct.SKU = sourceProduct.StockNumber;
                                    company.Product.Add(newProduct);
                                }
                            }
                            _dbRiv.SaveChanges();  // ### THIS BREAKS ### //
                        }
                    }
                }
                break;
        }
    }
}

模型 #1 - 该模型位于我们开发服务器上的数据库中。 模型 #1
http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/bdb2b000-6e60-4af0-a7a1-2bb6b05d8bc1/Model1.png

模型 #2 - 该模型位于我们的产品服务器上的数据库中,并且每天通过自动提要进行更新。 替代文字
http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png

注意 - 模型 #1 中的红色圆圈项目是我用来“映射”到模型 #2 的字段。请忽略模型 #2 中的红色圆圈:这是我现在回答的另一个问题。

注意:我仍然需要进行 isDeleted 检查,以便如果它已从我们客户的库存中消失,我可以从 DB1 中软删除它。

使用这个特定的代码,我想要做的就是将 DB1 中的公司与 DB2 中的客户连接起来,从 DB2 中获取他们的产品列表,然后将其插入到 DB1
中(如果它还没有的话)。第一次通过应该是一个完整的库存。每次它在那里运行时都不会发生任何事情,除非新的库存在一夜之间进入饲料。

所以最大的问题 - 我如何解决我得到的交易错误? 我是否需要每次通过循环删除并重新创建我的上下文(对我来说没有意义)?


阅读 102

收藏
2022-03-04

共1个答案

小编典典

在大量拔出头发后,我发现foreach毛圈是罪魁祸首。需要发生的是调用 EF,但将其返回到IList<T>该目标类型,然后在IList<T>.

例子:

IList<Client> clientList = from a in _dbFeed.Client.Include("Auto") select a;
foreach (RivWorks.Model.NegotiationAutos.Client client in clientList)
{
   var companyFeedDetailList = from a in _dbRiv.AutoNegotiationDetails where a.ClientID == client.ClientID select a;
    // ...
}
2022-03-04