【问题标题】:There is already a generated proxy type for the object layer type 'MyProject.Model.Applications'已经为对象层类型“MyProject.Model.Applications”生成了代理类型
【发布时间】:2026-02-09 20:55:01
【问题描述】:

我使用的是代码优先方法。我正在设置一个每天将表行从 sourcedb 复制到 targetdb 的过程。我还需要维护两者的主键值。 (这是必需的)即两个 dbs 对于给定的行应该具有相同的主键。

我通过引用相同的类创建了 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();
    }

还有一些外键约束。但无论那里有什么,这两种情况都有共同点。

【问题讨论】:

    标签: entity-framework model-view-controller ef-code-first dbcontext


    【解决方案1】:

    dbContext.Configuration.LazyLoadingEnabled = false;AsNoTracking() 都不会阻止 EF 在源上下文中创建代理对象,这反过来又会阻止在另一个上下文中使用它们。

    你真正需要的是关闭ProxyCreationEnabled

    获取或设置一个值,该值指示框架是否在创建实体类型的实例时创建动态生成的代理类的实例。请注意,即使使用此标志启用代理创建,也只会为满足被代理要求的实体类型创建代理实例。默认情况下启用代理创建。

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

    dbContext.Configuration.LazyLoadingEnabled = false;
    

    dbContext.Configuration.ProxyCreationEnabled = false;
    

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

    【讨论】:

    • 这似乎不起作用。无论此行如何,都会发生错误。也许它必须在配置时设置,不能在需要时关闭?
    最近更新 更多