질문 : Entity Framework의 SqlException-세션에서 실행중인 다른 스레드가 있으므로 새 트랜잭션이 허용되지 않습니다.
현재이 오류가 발생합니다.
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-이 모델은 Dev Server의 데이터베이스에 있습니다. 모델 # 1 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/bdb2b000-6e60-4af0-a7a1-2bb6b05d8bc1/Model1.png
모델 # 2-이 모델은 Prod Server의 데이터베이스에 있으며 자동 피드를 통해 매일 업데이트됩니다. 대체 텍스트 http://content.screencast.com/users/Keith.Barrows/folders/Jing/media/4260259f-bce6-43d5-9d2a-017bd9a980d4/Model2.png
참고-모델 # 1의 빨간색 원으로 표시된 항목은 모델 # 2에 "매핑"하는 데 사용하는 필드입니다. 모델 # 2의 빨간색 원은 무시하십시오.이 질문은 제가 가지고 있던 다른 질문에 대한 답변입니다.
참고 : 클라이언트의 인벤토리에서 사라진 경우 DB1에서 소프트 삭제할 수 있도록 isDeleted 확인을 입력해야합니다.
이 특정 코드를 사용하여 내가 원하는 것은 DB1의 회사를 DB2의 클라이언트와 연결하고 DB2에서 제품 목록을 가져와 아직없는 경우 DB1에 삽입하는 것입니다. 처음으로 전체 인벤토리를 가져와야합니다. 밤새 새 인벤토리가 피드에 들어오지 않는 한 아무 일도 일어나지 않은 후 실행될 때마다.
그래서 질문-내가 얻는 거래 오류를 어떻게 해결합니까? 루프를 통과 할 때마다 내 컨텍스트를 삭제하고 다시 만들어야합니까 (이치에 맞지 않음)?
답변
머리카락을 많이 뽑은 후 나는 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;
// ...
}
출처 : https://stackoverflow.com/questions/2113498/sqlexception-from-entity-framework-new-transaction-is-not-allowed-because-ther