来自实体框架的 SqlException - 不允许新事务,因为会话中有其他线程正在运行 [英] SqlException from Entity Framework - New transaction is not allowed because there are other threads running in the session
问题描述
我目前收到此错误:
System.Data.SqlClient.SqlException:不允许新事务,因为会话中有其他线程正在运行.
System.Data.SqlClient.SqlException: New transaction is not allowed because there are other threads running in the session.
运行此代码时:
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
Model #1 - This model sits in a database on our Dev Server. Model #1 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/bdb2b000-6e60-4af0-a7a1-2bb6b05d8bc1/Model1.png
模型 #2 - 此模型位于我们的 Prod 服务器上的数据库中,每天通过自动提要进行更新.替代文字 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png
Model #2 - This model sits in a database on our Prod Server and is updated each day by automatic feeds. alt text http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png
注意 - 模型 #1 中的红色圆圈项是我用来映射"到模型 #2 的字段.请忽略模型 2 中的红色圆圈:这是我的另一个问题,现在已得到解答.
Note - The red circled items in Model #1 are the fields I use to "map" to Model #2. Please ignore the red circles in Model #2: that is from another question I had which is now answered.
注意:我仍然需要进行 isDeleted 检查,以便在它从我们客户的库存中删除时我可以从 DB1 中软删除它.
Note: I still need to put in an isDeleted check so I can soft delete it from DB1 if it has gone out of our client's inventory.
我想要做的就是使用这个特定的代码,将 DB1 中的一家公司与 DB2 中的一个客户连接起来,从 DB2 获取他们的产品列表,如果它尚未存在,则将其插入到 DB1 中.第一次通过应该是完整的库存.每次在那里运行后,除非新的库存在一夜之间进入提要,否则什么都不应该发生.
All I want to do, with this particular code, is connect a company in DB1 with a client in DB2, get their product list from DB2 and INSERT it in DB1 if it is not already there. First time through should be a full pull of inventory. Each time it is run there after nothing should happen unless new inventory came in on the feed over night.
所以最大的问题是 - 如何解决我遇到的交易错误?我是否需要每次通过循环删除并重新创建我的上下文(对我来说没有意义)?
推荐答案
经过多次梳理后,我发现 foreach
循环是罪魁祸首.需要发生的是调用 EF,但将其返回到该目标类型的 IList
,然后在 IList
上循环.
After much pulling out of hair I discovered that the foreach
loops were the culprits. What needs to happen is to call EF but return it into an IList<T>
of that target type then loop on the 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;
// ...
}
这篇关于来自实体框架的 SqlException - 不允许新事务,因为会话中有其他线程正在运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!