I am using a code first approach. I am setting up a process to copy table rows from sourcedb to targetdb on daily basis. Also I need to maintain the primary key values in both. (this is required) i.e. Both dbs should have same primary key for given row.
I have created 2 different contexts by referring same classes. Both contexts are intact. I am getting all the rows from sourcedb into a list of object and passing it to another context to insert that range into targetdb. But while doing so I am getting the error as 'There is already a generated proxy type for the object layer type 'MyProject.Model.Applications'. This occurs when the same object layer type is mapped by two or more different models in an AppDomain.
I have checked some other links. But nothing has worked so far. I have also checked is it possible to share POCO object between two DbContext?.
Following is some pseudo code,
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();
}
Also there are some foreign key constraints. But whatever is there, common to both contexts.
Neither dbContext.Configuration.LazyLoadingEnabled = false; nor AsNoTracking() prevents EF from creating proxy objects in the source context, which in turn prevents using them in another context.
What you really need is to turn ProxyCreationEnabled off:
Gets or sets a value indicating whether or not the framework will create instances of dynamically generated proxy classes whenever it creates an instance of an entity type. Note that even if proxy creation is enabled with this flag, proxy instances will only be created for entity types that meet the requirements for being proxied. Proxy creation is enabled by default.
It also prevents lazy loading because it depends on proxy class intercepting the virtual properties. So simply replace
dbContext.Configuration.LazyLoadingEnabled = false;
with
dbContext.Configuration.ProxyCreationEnabled = false;
and the issue will be resolved. Just note that this doesn't mean the code will work correctly. The entities must have explicit FKs defined (not simply navigation properties) and the related entities must be processed first to prevent FK constraint violation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With