【问题标题】:Why does FirstOrDefault call SaveChanges?为什么 FirstOrDefault 调用 SaveChanges?
【发布时间】:2013-11-12 13:33:18
【问题描述】:

在下面的代码中,ConfigSetting 是一个实体,Db 是我的上下文。 当我在调试器中进入以下行时

 ConfigSetting config = this.Db.ConfigSettings.FirstOrDefault(o => o.Name == kSiteGuid);

我发现我在上下文 SaveChanges 事件中。

数据库已经存在,所以 EF 不应该尝试播种它。

调用栈是

SBD.Syrius.DataLayer.dll!SBD.Syrius.DataLayer.Context.SaveChanges() 第 338 行 C# EntityFramework.dll!System.Data.Entity.Migrations.DbMigrator.SeedDatabase() + 0x9e 字节
EntityFramework.dll!System.Data.Entity.Migrations.Infrastructure.MigratorBase.SeedDatabase() + 0x40 字节
EntityFramework.dll!System.Data.Entity.Migrations.DbMigrator.Upgrade(System.Collections.Generic.IEnumerable pendingMigrations, string targetMigrationId, string lastMigrationId) + 0x38c bytes
EntityFramework.dll!System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgrade(System.Collections.Generic.IEnumerable pendingMigrations, string targetMigrationId, string lastMigrationId) + 0x5e 字节
EntityFramework.dll!System.Data.Entity.Migrations.DbMigrator.Update(string targetMigration) + 0x547 字节
EntityFramework.dll!System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update() + 0x34 字节 EntityFramework.dll!System.Data.Entity.MigrateDatabaseToLatestVersion.InitializeDatabase(SBD.Syrius.DataLayer.Context 上下文) + 0xa3 字节 EntityFramework.dll!System.Data.Entity.Database.SetInitializerInternal.AnonymousMethod_0(System.Data.Entity.DbContext c) + 0xd0 字节
EntityFramework.dll!System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization.AnonymousMethod
_6() + 0x55 字节 EntityFramework.dll!System.Data.Entity.Internal.InternalContext.PerformInitializationAction(System.Action 动作) + 0x74 字节
EntityFramework.dll!System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() + 0x17d 字节
EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase.AnonymousMethod__4(System.Data.Entity.Internal.InternalContext c) + 0x30 字节
EntityFramework.dll!System.Data.Entity.Internal.RetryAction.PerformAction(System.Data.Entity.Internal.InternalContext 输入) + 0xa2 字节
EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(System.Action action) + 0x181 bytes
EntityFramework.dll!System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() + 0xa5 字节
EntityFramework.dll!System.Data.Entity.Internal.InternalContext.Initialize() + 0x46 字节
EntityFramework.dll!System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(System.Type entityType) + 0x2d 字节 EntityFramework.dll!System.Data.Entity.Internal.Linq.InternalSet.Initialize() + 0x97 字节
EntityFramework.dll!System.Data.Entity.Internal.Linq.InternalSet.InternalContext.get() + 0x32 字节 EntityFramework.dll!System.Data.Entity.Infrastructure.DbQuery.System.Linq.IQueryable.Provider.get() + 0x8c 字节
System.Core.dll!System.Linq.Queryable.FirstOrDefault(System.Linq.IQueryable source, System.Linq.Expressions.Expression> 谓词) + 0x55 字节
SBD.Syrius.DataLayer.dll!SBD.Syrius.DataLayer.DataHelper.FindOrCreateSite() 第 262 行 + 0x1d6 字节 C# SBD.Syrius.UI.exe!SBD.Syrius.UI.Program.Main(string[] args) 第 34 行 + 0x24 字节 C# [本机到托管转换]
[托管到本地转换]
mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x66 bytes Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x8d 字节
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态, bool preserveSyncCtx) + 0x285 字节 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态, bool preserveSyncCtx) + 0x9 bytes
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态) + 0x57 字节
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 字节
[本机到托管转换]

调试器显示

“SBD.Syrius.UI.vshost.exe”(托管 (v4.0.30319)):已加载“E:\EShared\Syrius6\syrius_syrius\SBD.Syrius.UI\bin\Debug\SBD.Syrius.Synchronisation。 dll',已加载符号。 System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的第一次机会异常 System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的第一次机会异常 System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的第一次机会异常 System.Data.Entity.dll 中出现“System.Data.EntityCommandExecutionException”类型的第一次机会异常 System.Data.Entity.dll 中出现“System.Data.EntityCommandExecutionException”类型的第一次机会异常 System.Data.Entity.dll 中出现“System.Data.EntityCommandExecutionException”类型的第一次机会异常 步入:跳过没有符号“System.Data.Entity.Infrastructure.DbContextInfo.CreateActivator.AnonymousMethod__0”的方法 步入:跳过没有符号“System.Data.Entity.Infrastructure.DbContextInfo.CreateInstance”的方法 步入:跳过没有符号'System.Data.Entity.Migrations.DbMigrator.SeedDatabase'的方法

[更新]

关于初始化器的信息

    private static string _connectionString;

    public Context()
        : base(_connectionString )
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>());

    }

    public Context(string connString)
        : base(connString)
    {

        _connectionString = connString;
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>());


    }

    public Context(string connString )
        : base(connString)
    {
        _connectionString = connString;

    }

对于配置类

namespace SBD.Syrius.DataLayer.Migrations
{

  using System.Data.Entity.Migrations;


  public sealed class Configuration : DbMigrationsConfiguration<SBD.Syrius.DataLayer.Context>
  {
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(SBD.Syrius.DataLayer.Context context)
    {

    }
  }
}

【问题讨论】:

  • 能否提供调试器?
  • 完成,我也禁用了“只是我的代码”并且能够看到调用堆栈
  • 你应该显示你的 Application_Start 方法,或者你正在配置你的 EF 初始化的任何地方。
  • 我不认为 MigrateDatabaseToLatestVersion 是你想要的。我认为这会迫使迁移,但我可能是错的。
  • 这就解释了。迁移中的 Up() 方法没有被调用。可能是因为数据库结构是最新的。在不需要时调用 SaveChanges 似乎令人困惑。有没有更好的方法来检查是否需要迁移?

标签: winforms entity-framework-5


【解决方案1】:

如果您查看调用堆栈,您会发现它正在进行数据库迁移。这是您对模型进行更改时发生的过程,并且需要更新数据库结构。

迁移发生后,EF 会调用 SeedDatabase,它允许您添加默认值。在 SeedDatabase 结束时,它调用 SaveChanges 来保存这些更改。

【讨论】:

  • 我同意它看起来像这样,但是我没有对我的模型进行更改。如果我在 PM> 中运行 Add_migration,则创建的迁移没有代码。
  • 它正在调用 InitializeDatabase。您是否将 DbInitializer 设置为 null?
  • 我没有将初始化程序设置为 null,因为我希望在删除数据库时进行初始化。
【解决方案2】:

当我尝试创建新实体时,在我的 UnitOfWork 的 GenericRepository.cs 中调用了此异常。

 public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }

轻松修复

在包管理器控制台中。添加新的迁移Add-Migration SomeMeaninglessName 并更新数据库Update-Database

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多