2

코드 첫 번째 접근 방식을 사용하고 있습니다. 매일 sourcedb에서 targetdb로 테이블 행을 복사하는 프로세스를 설정 중입니다. 또한 나는 둘 다에서 기본 키 값을 유지해야합니다. (필수) 즉, 두 dbs는 주어진 행에 대해 동일한 기본 키를 가져야합니다.'MyProject.Model.Applications'객체 계층 유형에 대해 이미 생성 된 프록시 유형이 있습니다.

동일한 클래스를 참조하여 2 가지 다른 컨텍스트를 만들었습니다. 두 상황 모두 손상되지 않습니다. sourcedb에서 모든 행을 객체 목록으로 가져와 다른 컨텍스트로 전달하여 해당 범위를 targetdb에 삽입합니다. 그러나 이렇게하는 동안 ''이라는 오류가 발생합니다. 이미 'MyProject.Model.Applications'객체 계층 유형에 대해 생성 된 프록시 유형이 있습니다. AppDomain에서 동일한 개체 계층 유형이 둘 이상의 다른 모델에 매핑되는 경우에 발생합니다.

다른 링크를 확인했습니다. 그러나 지금까지 아무 일도 없었다. 나는 is it possible to share POCO object between two DbContext?도 확인했다.

다음

using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, TimeSpan.FromSeconds(6000))) 
    { 
     using (var dbContext = new SourceDbContext()) 
     { 

     DateTime dateToBeCompared = DateTime.UtcNow.Date.AddMonths(-11); 
     dbContext.Configuration.LazyLoadingEnabled = false; 
     dbContext.Configuration.AutoDetectChangesEnabled = false; 
      //get data from application related tables. 
      var applications = dbContext.Applications.AsNoTracking().Where(a => a.UpdatedOn <= dateToBeCompared) 
            .ToList(); 
      using (var connection1 = new System.Data.SqlClient.SqlConnection("TargetDbConnectionString")) 
      { 
       connection1.Open(); 
       using (var targetDbContext = new TargetDbContext(connection1, true)) 
        using (TransactionScope tsSuppressed = new TransactionScope(TransactionScopeOption.Suppress)) 
        { 
         targetDbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [dbo].[Applications] ON"); 
        } 

        try 
        { 
         targetDbContext.Applications.AddRange(applications); 
         targetDbContext.SaveChanges(); 
        } 
        catch (Exception ex) 
        { 
         throw; 
        } 

        using (TransactionScope tsSuppressed = new TransactionScope(TransactionScopeOption.Suppress)) 
        { 
         targetDbContext.Database.ExecuteSqlCommand("SET IDENTITY_INSERT [dbo].[Applications] OFF"); 
        } 
       } 

       connection1.Close(); 
      } 
     scope.Complete(); 
    } 

또한 일부 외래 키 제약 조건이 있습니다, 일부 의사 코드입니다. 그러나 거기에있는 것이 무엇이든, 두 상황에 공통적입니다.

답변

3

dbContext.Configuration.LazyLoadingEnabled = false;AsNoTracking()도 EF가 원본 컨텍스트에서 프록시 개체를 만들지 못하게하므로 다른 컨텍스트에서 사용할 수 없습니다.

은 무엇 당신이 정말로 필요한 것은 떨어져 ProxyCreationEnabled을 설정하는 것입니다 :

가져하거나 엔티티 타입의 인스턴스를 생성 할 때마다 프레임 워크가 동적으로 생성 된 프록시 클래스의 인스턴스를 생성할지 여부를 나타내는 값을 가져 오거나 설정합니다. 이 플래그로 프록시 작성이 가능하더라도 프록시 인스턴스에 대한 요구 사항을 충족시키는 엔티티 유형에 대해서만 프록시 인스턴스가 작성됩니다. 프록시 생성은 기본적으로 사용됩니다.

또한 가상 속성을 가로 채는 프록시 클래스에 의존하기 때문에 지연로드가 방지됩니다. 그래서 단순히

dbContext.Configuration.ProxyCreationEnabled = false; 

dbContext.Configuration.LazyLoadingEnabled = false; 

를 교체하고 문제가 해결 될 것입니다. 단지 이것이 코드가 올바르게 작동한다는 것을 의미하지는 않습니다. 엔티티에는 명시 적 FK가 정의되어 있어야하며 (탐색 속성이 아 니라) FK 제약 조건 위반을 방지하려면 관련 엔티티를 먼저 처리해야합니다.

+0

감사합니다. Ivan. 좋은 작품! – Pavvy