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在源上下文中创建代理对象,从而阻止EF在另一个上下文中使用它们。

你真正需要的是把ProxyCreationEnabled关:

获取或设置一个值,指示每当它创建了一个实体类型的实例框架是否会建立动态生成的代理类的实例。请注意,即使通过此标志启用代理创建,代理实例也只会为符合被代理要求的实体类型创建。代理创建是默认启用的。

它还可以防止延迟加载,因为它依赖于代理类拦截虚拟属性。所以,简单地更换

dbContext.Configuration.LazyLoadingEnabled = false; 

dbContext.Configuration.ProxyCreationEnabled = false; 

和问题将得到解决。请注意,这并不意味着代码将正常工作。实体必须定义明确的FK(不仅仅是导航属性),并且必须首先处理相关实体以防止违反FK约束。

+0

谢谢伊万。非常棒! – Pavvy

相关问题